Call WCF Service Through Javascript, AJAX, or JQuery - asp.net

I created a number of standard WCF Services (Service Contract and Host (svc) are in separate assemblies). I fired up a Web Site in IIS to host the Services (i.e., address is http://services:1000/wcfservices.svc).
Then in my Web Site project I added the reference. I am able to call the services normally. I am needed to call some of the services client side. Not sure if I should be looking at articles calling WCF services through AJAX, JQuery, or JSON enabled WCF Services. Can anyone provide any thoughts or experience with configuring as such?
Some of the changes I made was adding the following to the Operation Contract:
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "SetFoo")]
void SetFoo(string Id);
Then this above the implementation of the interface:
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]
Then in the service webconfig I have this (parens are angle brackets):
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
<baseAddressPrefixFilters>
<add prefix="http://services:1000/wcfservices.svc/"/>>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
<serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
Then in the client side I attempted this:
<asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server">
<compositeScript>
<Scripts>
<asp:ScriptReference
Path="http://Flixsit:1000/FlixsitWebServices.svc" />
</Scripts>
</CompositeScript>
</asp:ScriptManagerProxy>
I am attempting to call the service like this in javascript:
wcfservices.SetFoo(string Id);
Nothing is working. If it is idea or a better solution to call JSON enable, JQuery, etc....I am willing to make any changes.
Thanks for any suggestions/tips provided....

The same origin policy will prevent the client from making AJAX calls to a service located in a different domain (different host) than the one serving up the web page. You can make this work using JSONP rather than JSON. You'll need to change your service to accept a callback function and deliver to the client a bit of javascript invoking this callback with the JSON data.

Related

Capture and modify http requests

I have an Asp.net MVC application, which is connected to many Asp.net Web Api services.
It consumes the services using HttpClient requests. These methods exists in SDK libraries.
Is it possible to inspect (sniff) the REST requests, and before being sent, to add additional information in the Headers?
All the Asp.Net Web APIs are on the same local network as the Asp.net MVC application.
I am not sure why do you call the REST api from the ASP.NET MVC controllers, you can call it directly from the Views using jQuery Ajax.
As for the inspection, you can do it using Fiddler, but you will have to update web.config for your ASP.NET MVC application by changing the default proxy like below:
<system.net>
<defaultProxy
enabled = "true" useDefaultCredentials = "true">
<proxy autoDetect="false" bypassonlocal="false"
proxyaddress="http://127.0.0.1:8888" usesystemdefault="false" />
</defaultProxy>
</system.net>
Make sure the proxy port for Fiddler is not changed from the default one 8888

WCF request doesn't flow via asp.net pipeline

I have a WCF service hosted in an asp.net application.
Here's the service (shortened):
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceContract(Name = Name, Namespace = Namespace)]
[ServiceBehavior(Name = Name, Namespace = Namespace)]
public class WcfMaintenanceFacade {...}
Here's hosting:
RouteTable.Routes.Add(new ServiceRoute("entity/maintenance/5.20", new ServiceHostFactory(), typeof(WcfMaintenanceFacade)));
And here's relevant config section:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
My service instantiates, the requests are coming in, and event HttpContext.Current is not empty.
There are two (major, for me) issues that I can't solve:
HttpContext.Current.Session is empty
Global.asax's Application_BeginRequest is never called
And yes, from the call stack it seems like the request is going through WCF activation pipeline, not ASP.net pipeline. So what am I doing wrong?
About the session, you handle it with OperationContext.Current.RequestContext instead of HttpContext.Current.Session.
HttpContext: Current is always null when accessed from within a WCF
service. Use
T:System.ServiceModel.OperationContext.Current.RequestContext instead.
Read more here: https://msdn.microsoft.com/en-us/library/aa702682.aspx
Application_BeginRequest are used by ASP.Net applications, but WCF works different from common web applications, thus BeginRequest could not be hit on each request.
The ASP.NET HTTP runtime handles ASP.NET requests but does not
participate in the processing of requests destined for WCF services
.... he WCF Service Model intercepts messages addressed to WCF
services and routes them through the WCF transport/channel stack
So, your problem can be related to this issue. This information is also available at the same link.
Hope it helps with your questions.
And the answer is simple (and, well, obvious):
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
Yes. RAMMFAR.
For me it is clear that these two technologies are not supposed to be working in the same application, and that's why they have two different pipelines. Service by the nature is an isolated thing. Now you just try to find a workaround, relying on the fact they both work on same IIS.
I would recommend you rather start from the goals, from what you want to achieve. If you need new service-like functionality integrated into native ASP.NET application you can
1) use ASMX services (will give you SAOP if you need it) and/or page methods
2) try to integrate WEB API in case you need JSON service.

Forms Authentication Cookie and WCF

I have an asp.net 4.0 application (client) that makes ajax/json calls to a http facade that then passes on the calls to our wcf service layer.
Users must authenticate on the client using forms authentication. The idea then being that the authentication cookie will be passed to and be accessible at the http facade. [Design based on Dino Esposito's book - Microsoft ASP.NET and AJAX: Architecting Web Applications]
The problem is, that at the facade, HttpContext.Current.User.Identity.Name is an empty string and IsAuthenticated is false.
I have enabled compatibility by adding the following to my system.ServiceModel section in my web.config (http facade level):
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
I have decorated my service with the following:
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Required)]
When I am debugging in the ajax/facade app I can see that cookies exist at HttpContext.Current.Request.Cookies. It appears that Anonymous is being used and not my authenticated user.
Both applications are running on the same IIS server.
Calls to the AJAX enabled wcf service are made via serviceProxy.js. Perhaps this method is not passing the necessary cookie?
WCF tracing is currently showing '..ASPXANONYMOUS=.....; ASP.NET_SessionId=....; .ASPXAUTH=.....' in the message log.
I get the feeling I am missing something simple but am too close to the problem.
Any suggestions welcomed.
I am not sure I completely understand the context of what you are trying to accomplish, but if these are two separate applications you are going to need to share machine keys in order to decrypt/encrypt the auth cookies in both.
in your web.config, make sure you have the following set:
<machineKey
validationKey="[generated key]"
validation="HMACSHA512"
decryptionKey="[generated key]"
decryption="AES"
/>
see how to generate these keys (and more info about them) on this codeproject article:
ASP.Net machineKey Generator - CodeProject
Let me know if this helps...

ServiceReference a self hosted WCF service

I am currently maintaining and developing a website which uses a lot of webservices in an ajax way.
Registering of the services is done in the aspx like this:
<asp:ScriptManagerProxy id="ScriptManager1" runat="server">
<services>
<asp:ServiceReference Path="WebServices/WSAdministrator.asmx"></asp:ServiceReference>
</services>
</asp:ScriptManagerProxy>
and consuming the services in the javascript is done like this
WSAdministrator.GetConsumerClubInfo(ConsumerClubId,
OnSucceededToGetConsumerClubInfo,
OnFailedToGetConsumerClubInfo);
I want to know if I can reference a self-hosted WCF service(on the same machine) this easily.
any suggestions?
EDIT: The WCF service is running on a windows service, it exposes both webHttpBinding and basicHttpBinding endpoints.
After Reading ASP.Net WCF Service with no App_Code , I realized that I should just create an svc file which will act as a reference to the service.
I created this svc file:
<%# ServiceHost Language="C#" Service="MyService.Namespace.Contract" %>
and in the web.config file I added these lines:
<services>
<service name="MyService.Namespace.Contract">
<endpoint address="setAddress" binding="basicHttpBinding" contract="MyService.Namespace.ContractInterface"/>
</service>
</services>
The address is working, but when I try to access the reference from the svc, I get the following error:
The type '', provided as the Service attribute value in the
ServiceHost directive could not be found.
What am I missing here?
Note: There have been some nice answers, but all to things I already know, my question is about how to reference my Self Hosted WCF service using asp.net so that I can use it from javascript, that's all, and for that I still have no answers...
I saw some replies to similar questions telling there should be an IIS hosted service acting as a "pipe" to the actual service, and then the ScriptManager should reference it, Maybe that's the only answer...
When you are self hosting your WCF Service you do not use .SVC file, but create the service host in your windows service's OnStart method in the following way.
WebServiceHost myServiceHost = null;
if (myServiceHost != null)
{
myServiceHost.Close();
}
myServiceHost = new WebServiceHost(typeof(YourClassName));
myServiceHost.Open();
If you want to host your service to support WebHttpBinding then the hosting class should be WebServiceHost and if you want to host wsHttpBinding or any other you should use ServiceHost.
Once service starts running clients can connect to it.
The following link contains step by step process for doing it.
If you have to support RESTful service that is able to talk to using AJAX and Jquery then you should go with WebServiceHost and you would decorate your operation contracts in the following way.
[ServiceContract()]
public interface IMyInterface
{
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "GetArray",
BodyStyle = WebMessageBodyStyle.Bare)]
MyArray[] GetArray();
}
You can find some info on this even in the following question.
Of course you can and it would look like this with WCF,
<asp:ServiceReference Path="~/WSAdministrator.svc" />
See Here and here for some examples.

Possible to invoke ASMX service with parameter via url query string?

I've got a asmx service that takes a single int parameter. I can open the URL to the service and see the service description screen. From here I can enter the query parameters into a form and invoke the web service.
Is there any way to invoke a web service directly from a URL/query string?
This doesnt work:
http://localhost:4653/MyService.asmx?op=MyWebMethod&intParameter=1
Any ideas? I'd really like to be able to do this from a standard link due to some deployment issues. Am I going to have to wrap the request in a normal aspx page?
You can decorate your method to allow HTTP GET requests, which should in turn do what you're looking for like so:
[WebMethod]
[ScriptMethod(UseHttpGet=true)]
public string MyNiftyMethod(int myint)
{
// ... code here
}
And edit the web.config :
<system.web>
<webServices>
<protocols>
<add name="HttpGet"/>
</protocols>
Then you'll be able to call this method like so:
http://mysite.com/Service.asmx/MyNiftyMethod?myint=12345
EDIT: Note that this method of performing GET requests does come with some security risks. According to the MSDN documentation for UseHttpGet:
Setting the UseHttpGet property to
true might pose a security risk for
your application if you are working
with sensitive data or transactions.
In GET requests, the message is
encoded by the browser into the URL
and is therefore an easier target for
tampering.
ASMX web services use SOAP. SOAP requests use only POST to invoke methods. You will need to generate a proxy client in your aspx page to invoke the web service. If you really need to use GET verbs to invoke web services you might need to use a different approach such as WCF REST.

Resources