Response.Write JSONP using JQuery and WCF - asp.net

UPDATE:
The service cannot be activated because it does not support ASP.NET compatibility. ASP.NET compatibility is enabled for this application. Turn off ASP.NET compatibility mode in the web.config or add the AspNetCompatibilityRequirements attribute to the service type with RequirementsMode setting as 'Allowed' or 'Required'.
when i try to access wcf service i get this error: the reason is HttpContext.Current is null, what should i do in this case? any help?
Object reference not set to an instance of an object.
System.Web.Script.Serialization.JavaScriptSerializer s = new System.Web.Script.Serialization.JavaScriptSerializer();
Person p = new Person() { FirstName = "First name", LastName= "last name" };
string json = s.Serialize(p);
System.Web.HttpContext.Current.Response.Write("jsoncallback" + json);} //error

HttpContext is an ASP.Net construct. If you want to be able to access it in your service, then you need to enable ASP.Net Compatibility for your service.
Either through the web.config:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
Or declaratively:
[AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Required)]
public class MyService : IMyService { ... }

If simple response write is the thing for you, then consider using a simple HttpHandler (by implementing the IHttpHandler interface). The Response object is not meant be used in a WCF Service...
If WCF however is the thing for you (maybe the stack of tech it offers is something you need), then consider using the plumming already there to output json:
[ServiceContract]
public interface IService
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.**Json**)]
String DoStuff();
}

Related

An item with the same key has already been added. IIS WCF Rest

I am hosting WCF Rest service with my Asp.net Application, and asp.net compatibility mode is on ,it is working fine
when I run app from visual studio but when I in IIS7 I get error while accessing the End Point says "An item with the same key has already been added."
MY Service Cod is.
[ServiceContract]
[AspNetCompatibilityRequirements
(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class RestService
{
[OperationContract]
[WebGet(UriTemplate = "Site/{Id}", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
public Site GetSite(string Id)
{
return new Site(1);
}
}
and global ASCX is
protected void Application_Start ()
{
RouteTable.Routes.Add(new ServiceRoute("Rest", new WebServiceHostFactory(), typeof(RestService)));
}
and web.config
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="false"/>
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
Note Every things working fine in VS2010 Mode but getting error in while Hosting IIS 7
and accessing http://example.com/rest/site/2
any Suggestion Please ?
In IIS Under Advance Setting then Enabledd Protocols I switched off https and it works fine.

WCF service with webHttpBinding not working when configurations are added in web.config

I have a very basic WCF service that I want to run on IIS as a RESTful service. Here is the service contract.
[ServiceContract]
interface IRestCameraWs
{
[OperationContract]
[WebGet(UriTemplate = "/cameras/{username}",ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Wrapped)]
CameraInfo[] GetUserCameras(string username);
[OperationContract]
[WebGet(UriTemplate = "/liveimage/{cameraId}",ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Wrapped)]
byte[] GetLiveImage(int cameraId);
//void GetLatestImage(int cameraId, out DateTime timestamp, out byte[] image);
[OperationContract]
[WebGet(UriTemplate = "/latestimage/{cameraId}", ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Wrapped)]
string GetLatestImageUrl(int cameraId);
}
There is a class which implements this contract called StopMotion.Business.WCFService.RestCameraWs. Then I added an .svc file in my web project with following markup.
<%# ServiceHost Service="StopMotion.Business.WCFService.RestCameraWsBase"%>
When I navigate to this service url, it shows me service home page and a link to wsdl definition. But when I add configuration in my web.config file to configure this service on webHttpBinding I get following error page from IIS express.
First I thought I am doing something wrong with configuration. Later I deleted the configuration and just changed the factory in svc file like
<%# ServiceHost Factory="System.ServiceModel.Activation.WebServiceHostFactory" Service="StopMotion.Business.WCFService.RestCameraWsBase"%>
WebServiceHostFactory is said to use webHttpBinding by default and we don't need to add this in configuration unless we need something more out of it. But changing factory also resulted in the same error page on IIS Express.
Any ideas what's going on here?
Looking in my configs, I remember that I had to declare the end point in the web.config and enableWebScript in the behavior. Part of the result looks somewhat like :
<endpoint address="json" binding="webHttpBinding" contract="svcservice.svc.IAuthsvc" bindingConfiguration="bc.svcservice.svc.AuthsvcJSON" behaviorConfiguration="epb.svcservice.svc.AuthsvcJSON"/>
.
.
.
.
<behavior name="epb.svcservice.svc.AuthsvcJSON">
<enableWebScript/>
</behavior>
Hope this can be helpful
The problem was with my method signatures. we can only have parameters of type string which are included in UriTemplate whereas some of methods were accepting parameters of type int like following.
[OperationContract]
[WebGet(UriTemplate = "/latestimage/{cameraId}",ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Wrapped)]
string GetLatestImageUrl(int cameraId);
When i debugged it on vs dev server, it laid the error on line for me but it seems that observing the error is more difficult in IIS Express even in the dev environment.

Orchard/MVC WCF Service Url with Area

Bertrand created a blog post to specify how to use IoC in WCF Modules for Orchard.
In 1.1, you can create a SVC file using the new Orchard host factory:
<%# ServiceHost Language="C#" Debug="true"
Service="MyModule.IMyService, MyAssembly"
Factory="Orchard.Wcf.OrchardServiceHostFactory, Orchard.Framework" %>
Then register your service normally as an IDependency but with service and operation contract attributes:
using System.ServiceModel;
namespace MyModule {
[ServiceContract]
public interface IMyService : IDependency {
[OperationContract]
string GetUserEmail(string username);
}
}
My question is that all of Orchard's modules are really area's. So how can you build a route that hits the svc file created in the area/module?
Should you use the full physical path to get to the svc file (tried that and it caused a web.config issue since it was bridging a site and area).
http://localhost/modules/WebServices/MyService.svc
Or do you create a ServiceRoute with WebServiceHostFactory/OrchardServiceHostFactory?
new ServiceRoute("WebServices/MyService", new OrchardServiceHostFactory(), typeof(MyService))
Whatever I try I get a 404 when trying to hit the resource. I was able to get this working using a wcf Application project and setting WCF as a stand alone application, my issues started when trying to bring it into Orchard/MVC.
UPDATE
Thanks for the help Piotr,
This is the steps I took to implement the service.
Routes.cs
new RouteDescriptor { Priority = 20,
Route = new ServiceRoute(
"Services",
new WebServiceHostFactory(),
typeof(MyService)) }
If I use OrchardServiceHostFactory() instead of WebServiceHostFactory() I get the following error.
Operation is not valid due to the current state of the object.
Orchard Root Web.Config
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
<standardEndpoints>
<webHttpEndpoint>
<!--
Configure the WCF REST service base address via the global.asax.cs file and the default endpoint
via the attributes on the <standardEndpoint> element below
-->
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
MyService
[ServiceContract]
public interface IMyService : IDependency
{
[OperationContract]
string GetTest();
}
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
class MyService : IMyService
{
public string GetTest()
{
return "test";
}
}
I couldn't get the service working by just modifying the module's web.config. I get the following error
ASP.NET routing integration feature requires ASP.NET compatibility.
UPDATE 2
Orchard Root Web.Config
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<!-- ... -->
</system.serviceModel>
Routes.cs
public IEnumerable<RouteDescriptor> GetRoutes() {
return new[] {
new RouteDescriptor { Priority = 20,
Route = new ServiceRoute(
"Services",
new OrchardServiceHostFactory(),
typeof(IMyService))
}
};
}
This works, the key here is that you must call typeof on the object that is referencing IDependency, WorkContextModule.IsClosingTypeOf cant handle the object that consumes the dependancy, it must take the Interface that it is directly called by.
As you stated, Orchard modules are areas in ASP.NET MVC terms, so the URL you provided is incorrect and should be:
http://localhost/Your.Orchard.Module/WebServices/MyService.svc
Where localhost is the virtual directory under which your app runs and /WebServices is a folder in the root of your module.
You can also create a service route programatically without problem. This article tells how to add new routes in Orchard. You can just assign a ServiceRoute to the Route property of a RouteDescriptor instead of a default MVC route (as shown in docs).
The question about adding ServiceRoute in area-enabled ASP.NET MVC app was asked before, check it out as it may help you out.
Btw - You may also check this SO question about prefixed service routes.
HTH

Make my WCF service return json

I am trying to make my WCF service method to return JSON-object, but it doesn't work, when I open in a web browser it shows xml.
How can I make this method return JSON?
I have inserted [WebGet(ResponseFormat = WebMessageFormat.Json)], but that didn't help
[WebGet(ResponseFormat = WebMessageFormat.Json)]
protected override IEnumerable<KeyValuePair<string, SampleItem>> OnGetItems()
{
// TODO: Change the sample implementation here
if (items.Count == 0)
{
items.Add("A", new SampleItem() { Value = "A" });
items.Add("B", new SampleItem() { Value = "B" });
items.Add("C", new SampleItem() { Value = "C" });
}
return this.items;
}
In order for this to work, you need to host this with the webHttpBinding and the WebServiceHostFactory in your web.config and service's *.svc file.
You didn't show any web.config or other config - so I cannot really tell what you're doing. But the JSON response format in the WebGet attribute is only supported in the REST-style WCF services. The WebGet attribute is ignored for any of the SOAP-based bindings, e.g. basicHttpBinding, wsHttpBinding, netTcpBinding and so on.
For more information on REST-style WCF Services, check out the WCF REST Developer Center and read up on how to set up and use REST-style WCF services.
Update: in order for your *.svc file to properly work as a REST service that uses the WebGet attribute and returns JSON, you need to make sure to specify the correct service host factory:
<%#ServiceHost Language="C#" Service="YourService"
Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>
By specifying the WebServiceHostFactory, you're telling the WCF runtime to use this service as a REST service, and then all the other pieces should automatically fall into place.
Have you also set the WebHttpBehaviour ? Otherwise, WebGet does not work. See MSDN
And this attribute applies to Service operations, not simple methods. You do not show the rest of your services, but the examples I've seen using WebGet had this attribute in the interface (service contract).

Impersonation WCF

I have a WCF service, hosted in IIS, which I require to impersonate the annon account.
in my Webconfig
<authentication mode="Windows"/>
<identity impersonate ="true"/>
Testing the following, with vs2008
public void ByRuleId(int ruleId)
{
try
{
string user = WindowsIdentity.GetCurrent().Name;
string name = Thread.CurrentPrincipal.Identity.Name;
........
//get the data as a string.
using (FileStream fs = File.Open(location, FileMode.Open))
using (StreamReader reader = new StreamReader(fs))
{
rawData = reader.ReadToEnd();
}
}
catch.....
}
this works. however if I add impersonation attribute
[OperationBehavior(Impersonation=ImpersonationOption.Required)]
public void ByRuleId(int ruleId)
this does not work with the error message
"Either a required impersonation level was not provided, or the provided impersonation level is invalid."
a little poking around I noticed the first way was authenticated by Kerboros and the second way just failed on authentication type
I am using the WCF client tool, to pass my credentials. this seems to be working.
Check the 'TokenImpersonationLevel' of identity of the current thread; you'll need it to be at least 'Impersonation' to perform operations on the machine that the service is running on.
Typically, if you are using a proxy client, you'll need to set the 'TokenImpersonationLevel' of the client:
http://www.devx.com/codemag/Article/33342/1763/page/4
the main goal of this was to get anon access, even tho MattK answer was a great help.
here is what i did to do so.
on the implementation of the WCF contract I added the
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class TransferFile : ITransferFile
and in the web.config
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled ="true" />
after this i was able to impersonate the anon account

Resources