简体   繁体   English

如何使用jquery Ajax将数据发布到WCF服务?

[英]How to post data to WCF Service using jquery Ajax?

I am facing issue in consuming WCF service using JQUERY AJAX. 我在使用JQUERY AJAX消费WCF服务时面临问题。 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: 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: 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 这是它的样子: http//screencast.com/t/b7tsqld6

See error : http://screencast.com/t/pWQNAlmMYS3 请参阅错误: 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: 看我的Global.asax ..我在这里做错了什么:

 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 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. 您需要在web.config中更改服务类的名称,并在jquery代码中更改您将调用它的URL。

I would try to set Access-Control-Allow-Credentials: true i web.config. 我会尝试设置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. 还可以尝试将Access-Control-Allow-Headers设置为与jquery ajax调用匹配的标头。 Should be "application/json", but check with fiddler (or similar) to be sure. 应该是“application / json”,但请与fiddler(或类似)确认。 Finally try setting the Access-Control-Request-Method: POST 最后尝试设置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. 我讨厌类似的问题,在尝试了不同的设置后,我在web.config中找到了一个实际工作的组合。 Good luck :) 祝好运 :)

UPDATE UPDATE

Also, I would make sure that the access-control-allow-credentials is in the same case- form as the other parameters. 此外,我将确保access-control-allow-credentials与其他参数的形式相同。 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. 我会尝试不使用localhost。 Setup your test environments on different servers with proper host names.At least Chrome has had problems handling cors on localhost. 使用正确的主机名在不同的服务器上设置测试环境。至少Chrome在localhost上处理cors时遇到问题。

According to http://www.html5rocks.com/en/tutorials/cors/ the Content-type of the request should be one of the following: 根据http://www.html5rocks.com/en/tutorials/cors/ ,请求的Content-type应该是以下之一:

  • application/x-www-form-urlencoded 应用程序/ x-WWW窗体-urlencoded
  • multipart/form-data 多部分/格式数据
  • text/plain 纯文本/

UPDATE 2 更新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: 当我对Sharepoint 2013服务器进行CORS设置时,我添加了这个并且一切正常:

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. 您需要在Access-Control-Allow-Origin添加请求的域而不是**可能不适用于所有浏览器,因为它存在安全问题 - 即OPTIONS请求中只允许请求的域,而不是*应该在选项中响应响应标题。 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() . 用请求的域名替换http://localhost ,以编程方式执行此操作,您可以使用它 - HttpContext.Current.Request.Headers["Origin"].ToString()

I have explained this in my blog in more detail- Blog , CodeProject 我已经在我的博客中更详细地解释了这一点 - BlogCodeProject

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM