How to call WCF service from javascript?

I am trying to call a WCF service from an ajax call using jQuery. I manage to call WCF from SOAP-UI and from Excel / VBA. My problem arises from the OPTIONS request that is being sent, and POST should not:

  • If I set the URL to http://mywcf/service.svc , the options are sent and I get the status 400 Bad Request , and the POST request is not sent. In this case, the HTTP/1.1 header is missing from the header (compared to the SOAP-UI headers).
  • If I set the URL to http://mywcf/service.svc HTTP/1.1 , send OPTIONS and I will get the status 200 OK , but the POST request will not be sent. In this case, HTTP/1.1 appears to be interpreted as a file name.

Can someone tell me how to call a POST action in WCF from javascript and add an HTTP/1.1 header without distorting the service url?

Here is an excerpt from my ajax call:

 var soapData = '' +'<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:mic="http://microsoft.wcf.documentation">' +' <soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wsrm="http://docs.oasis-open.org/ws-rx/wsrm/200702">' +' <wsrm:Sequence>' +' <wsrm:Identifier>s:Sender a:ActionNotSupported</wsrm:Identifier>' +' <wsrm:MessageNumber>1</wsrm:MessageNumber>' +' </wsrm:Sequence>' +' <wsa:Action>http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence</wsa:Action>' +' <wsa:ReplyTo>' +' <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>' +' </wsa:ReplyTo>' +' <wsa:MessageID>uuid:'+ MsgUid +'</wsa:MessageID>' +' <wsa:To>'+ Url +'</wsa:To>' +' </soap:Header>' +' <soap:Body xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm">' +' <wsrm:CreateSequence>' +' <wsrm:AcksTo xmlns:wsa="http://www.w3.org/2005/08/addressing">' +' <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>' +' </wsrm:AcksTo>' +' <wsrm:Offer>' +' <wsrm:Identifier>urn:soapui:'+ SeqUid +'</wsrm:Identifier>' +' </wsrm:Offer>' +' </wsrm:CreateSequence>' +' </soap:Body>' +'</soap:Envelope>'; $.ajax({ type: 'POST', url: 'http://mywcf/service.svc', // with or without +' HTTP/1.1' data: soapData, contentType: 'application/soap+xml;charset=UTF-8', dataType: 'xml' }); 

Values ​​in my WCF web.config :

 <system.webServer> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Methods" value="POST, OPTIONS" /> <add name="Access-Control-Allow-Headers" value="*" /> </customHeaders> </httpProtocol> </system.webServer> 
+5
source share
3 answers

To use a web service using jQuery, i.e. to call a WCF service, you either use jQuery.ajax () or jQuery.getJSON (). In this article, I used the jQuery.ajax () method.

To specify a query, first define a variable. This will be useful if you call several methods and create another js file to call the WCF service.

 <script type="text/javascript"> var Type; var Url; var Data; var ContentType; var DataType; var ProcessData; 

The following function initializes the variables defined above to call the service.

 function WCFJSON() { var userid = "1"; Type = "POST"; Url = "Service.svc/GetUser"; Data = '{"Id": "' + userid + '"}'; ContentType = "application/json; charset=utf-8"; DataType = "json"; varProcessData = true; CallService(); } 

The CallService function sends requests to the service, setting the data to $ .ajax.

 // Function to call WCF Service function CallService() { $.ajax({ type: Type, //GET or POST or PUT or DELETE verb url: Url, // Location of the service data: Data, //Data sent to server contentType: ContentType, // content type sent to server dataType: DataType, //Expected data format from server processdata: ProcessData, //True or False success: function(msg) {//On Successfull service call ServiceSucceeded(msg); }, error: ServiceFailed// When Service call fails }); } function ServiceFailed(result) { alert('Service call failed: ' + result.status + '' + result.statusText); Type = null; varUrl = null; Data = null; ContentType = null; DataType = null; ProcessData = null; } 

Note. The following code checks the result.GetUserResult statement, so your result object gets the property of your service method name + Result. Otherwise, it will give an error, like an object not found in Javascript.

 function ServiceSucceeded(result) { if (DataType == "json") { resultObject = result.GetUserResult; for (i = 0; i < resultObject.length; i++) { alert(resultObject[i]); } } } function ServiceFailed(xhr) { alert(xhr.responseText); if (xhr.responseText) { var err = xhr.responseText; if (err) error(err); else error({ Message: "Unknown server error." }) } return; } $(document).ready( function() { WCFJSON(); } ); </script> 
+1
source

Add webHttpBinding endpoint

  <services> <service name="Contract"> <endpoint address="json" binding="webHttpBinding" contract="IContract" bindingConfiguration="ActionsHttpBinding" behaviorConfiguration="ActionrestfulBehavior"/> </service> 

then call the endpoint from ajax as a message or receive, see example below:

  var data = JSON.stringify({ param1: val1, param2: val2 }); $.ajax({ url: "http://mywcf/service.svc/json/FunctionName", type: "POST", data: data, contentType: "application/json; charset=utf-8", dataType: "json", processData: true }).then(function (rsutlt) { }).fail(function (fail) { }); 
0
source

Add the code below to your global.asax.cs file and remove customHeaders from your web configuration.

 protected void Application_BeginRequest(object sender, EventArgs e) { HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); if (HttpContext.Current.Request.HttpMethod == "OPTIONS") { //These headers are handling the "pre-flight" OPTIONS call sent by the browser HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000"); HttpContext.Current.Response.End(); } } 

Also you need to remove OPTIONSVerbHandler to enable cors.

  <system.webServer> <validation validateIntegratedModeConfiguration="false" /> <handlers> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <remove name="OPTIONSVerbHandler" /> <remove name="TRACEVerbHandler" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> </system.webServer> 
0
source

Source: https://habr.com/ru/post/1269230/


All Articles