I am facing issue in consuming WCF service using JQUERY AJAX. I know this is cross domain issue and have read alot of solution about it. but none worked for me. Below is all the related code. Can anyone please help me out?
Thanks
[OperationContract]
[WebInvoke(Method = "POST",BodyStyle=WebMessageBodyStyle.Bare,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
[return: MessageParameter(Name = "result")]
public ServiceSearchResponse GetSearchResults(ServiceSearchParams sParams)
{
/// search function
}
JQUERY:
$.ajax({
type: 'POST',
url: "http://myserviceurl.com/GetSearchResults",
data: p,
contentType: "application/json; charset=utf-8",
dataType: 'json',
crossDomain: true,
success: function (data) {
alert(data);
},
failure: function (response) {
alert('failed');
},
error: function (response) {
alert(JSON.stringify(response));
}
});
Webconfig:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
</system.webServer>
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="webHttpBinding" bindingConfiguration="" />
</protocolMapping>
<behaviors>
<serviceBehaviors>
<behavior name="DefaultServiceBehavior">
<!--Added DefaultServiceBehavior referenced at service tag above-->
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="myserives.services.AppServicesAspNetAjaxBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<services>
<service name="mypackage.services.MyServices">
<endpoint address="" behaviorConfiguration="myserives.services.AppServicesAspNetAjaxBehavior" binding="webHttpBinding"
bindingConfiguration="LargeSizeMessages" contract="myContractName" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="LargeSizeMessages" maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647" crossDomainScriptAccessEnabled="true">
<security mode="None" />
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
This is how it looks like: http://screencast.com/t/b7tsqld6
See error : http://screencast.com/t/pWQNAlmMYS3
And nothing in post data. though im posting data.
--- UPDATE
See my Global.asax .. i am doing something wrong here:
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpContext.Current.Response.Cache.SetNoStore();
EnableCrossDmainAjaxCall();
}
private void EnableCrossDmainAjaxCall()
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin",
"*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods",
"GET, POST");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials",
"true");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers",
"Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age",
"1728000");
HttpContext.Current.Response.End();
}
}
Here is a piece of working code.
Interface
[ServiceContract]
public interface IDataService
{
[OperationContract]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json,BodyStyle=WebMessageBodyStyle.WrappedResponse)]
List<RequestData> GetUser(RequestData data);
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "UsersList/{id}",RequestFormat=WebMessageFormat.Json,BodyStyle=WebMessageBodyStyle.WrappedResponse)]
RequestData UsersList(string id);
}
Class implementing interface
public class DataService : IDataService
{
public List<RequestData> GetUser(RequestData data)
{
List<RequestData> list = new List<RequestData>();
if (data.Name.ToUpper() == "MAIRAJ")
{
list.Add(new RequestData
{
Name = "Mairaj",
Age = 25,
Address = "Test Address"
});
list.Add(new RequestData
{
Name = "Ahmad",
Age = 25,
Address = "Test Address"
});
}
return list;
}
public RequestData UsersList(string userId)
{
return new RequestData
{
Name = "Mairaj",
Age = 25,
Address = "Test Address"
};
}
}
Custom Class
As i am passing object of this class as parameter to method and returning object of this so i am using this. You may not need it.
[DataContract]
public class RequestData
{
[DataMember]
public string Name { get; set; }
[DataMember]
public int Age { get; set; }
[DataMember]
public string Address { get; set; }
}
Web.Config
<configuration>
<configSections>
</configSections>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="EndpBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ServiceBehavior" name="WCFWebApp.DataService">
<endpoint address="" binding="webHttpBinding" contract="WCFWebApp.IDataService" behaviorConfiguration="EndpBehavior"/>
</service>
</services>
</system.serviceModel>
</configuration>
And here is how you call it
var Data = {
Name: "Mairaj",
Age: 20,
Address: "Test Address"
//userId:1
};
$.ajax({
type: "POST",
url: "/DataService.svc/GetUser",
dataType: "JSON",
data: JSON.stringify(Data),
contentType: "application/json; charset=utf-8",
success: function (data) {
alert("Data is " + data);
},
error: function () {
}
});
You need to change name of service classes in web.config and url in jquery code from where you will call it.
I would try to set Access-Control-Allow-Credentials: true i web.config. Also try setting the Access-Control-Allow-Headers to the header that match your jquery ajax call. Should be "application/json", but check with fiddler (or similar) to be sure. Finally try setting the Access-Control-Request-Method: POST
I hade similar problems and after experimenting with different settings i web.config I managed to find a combination that actually worked. Good luck :)
UPDATE
Also, I would make sure that the access-control-allow-credentials is in the same case- form as the other parameters. Ie Access-control-allow-credentials. I don't really have any source on this, but just in case :)
I would try this without using localhost. Setup your test environments on different servers with proper host names.At least Chrome has had problems handling cors on localhost.
According to http://www.html5rocks.com/en/tutorials/cors/ the Content-type of the request should be one of the following:
UPDATE 2
More things you could try: Add:
$.support.cors = true;
before the
$.ajax({ ...
I think that the problems could be cased by incorrect content type. When I did a CORS setup to a Sharepoint 2013 server I added this and it all worked:
headers: {
"accept": "application/json;odata=verbose;charset=utf-8",
"content-type":"application/json;odata=verbose;charset=utf-8"
},
That content-type might not be relevant for you, but I might be important to specify like that.
You need to add requested domain in Access-Control-Allow-Origin
instead of *
, *
might not work in all browsers , as it a security issue - ie only requested domain should be allowed in OPTIONS
request, not * should be responded in options response header. To solve this, you need to change that code to following.
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost");
Replace http://localhost
with requested domain name, to do it programatically you can use this - HttpContext.Current.Request.Headers["Origin"].ToString()
.
I have explained this in my blog in more detail- Blog , CodeProject
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.