How to post data to WCF service using jquery Ajax?

I am facing a problem while using WCF service using JQUERY AJAX. I know this is a cross domain problem and have read a lot about this solution. but none worked for me. Below is all the related code. Can anyone help me?

thank

 [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: http://screencast.com/t/b7tsqld6

See the error: http://screencast.com/t/pWQNAlmMYS3

And nothing in the postal data. although I am posting data.

--- UPDATE

See my Global.asax .. I am doing something wrong:

 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();
            }
        }

      

+3


source to share


3 answers


Here's a snippet 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 implementation 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

Since I am passing an object of this class as a parameter to a method and returning an object, so I am using that. You may not need this.



[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 this is what 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 the name of the service classes in web.config and url in your jquery code from where you call it.

+1


source


I would try to set Access-Control-Allow-Credentials: true i web.config. Also try setting Access-Control-Allow-Headers to a header that matches your jquery ajax call. Should be "application / json", but be sure to test with a fiddler (or similar). Finally try setting Access-Control-Request-Method: POST

I had similar problems and after experimenting with different settings on my web.config I was able to find a combination that actually worked. Good luck :)

UPDATE

Also, I would make sure the access-control-allow-credential is in the same case as the other options. That is, Access-Control-Allow-Credentials. I don't actually have the source, but just in case :)

I would try this without using localhost. Set up test environments on different servers with correct hostnames. At the same time, Chrome was having trouble handling corsa on localhost.

According to http://www.html5rocks.com/en/tutorials/cors/ , the content type of the request must be one of the following:

  • application / x-www-form-urlencoded
  • multipart / form-data
  • Text / plain

UPDATE 2



Other things you could try: Add:

$.support.cors = true;

      

before

$.ajax({ ...

      

I think the problems might be imposed by the wrong type of content. When I installed CORS for Sharepoint Server 2013, 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"
},

      

This content type may not be relevant to you, but it might be important for me to specify it.

0


source


You need to add the requested domain in Access-Control-Allow-Origin

instead *

, *

may not work in all browsers as this is a security issue - that is, only the requested domain should be allowed in the request OPTIONS

, not * should respond in the parameters response header. To fix this problem, you need to change this code as follows.

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost");

Replace with the http://localhost

requested domain name to do this programmatically, you can use this - HttpContext.Current.Request.Headers["Origin"].ToString()

.

I explained this on my blog in more detail - Blog , CodeProject

0


source







All Articles