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

时间:2015-06-25 14:51:39

标签: jquery asp.net wcf wcf-security

我在使用JQUERY AJAX消费WCF服务时面临问题。我知道这是跨域问题,已经阅读了很多关于它的解决方案。但没有一个对我有用。以下是所有相关代码。有人可以帮帮我吗?

由于

 [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>

这是它的样子: http://screencast.com/t/b7tsqld6

查看错误: http://screencast.com/t/pWQNAlmMYS3

发布数据中没有任何内容。虽然我发布了数据。

---更新

请参阅我的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();
            }
        }

3 个答案:

答案 0 :(得分:4)

这是一段工作代码。

<强>接口

[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);



    }

类实现界面

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"
                };
         }

    }

自定义类

当我将此类的对象作为参数传递给方法并返回此对象时,我正在使用此。你可能不需要它。

[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>

这就是你怎么称呼它

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

您需要更改web.config中的服务类名称,并在jquery代码中更改您将调用它的URL。

答案 1 :(得分:0)

我会尝试设置 Access-Control-Allow-Credentials:true i web.config。 还可以尝试将 Access-Control-Allow-Headers 设置为与jquery ajax调用匹配的标头。应该是&#34; application / json&#34;,但请与fiddler(或类似)核实以确定。 最后尝试设置访问控制请求方法:POST

我喜欢类似的问题,在尝试了不同的设置之后我在web.config中找到了一个实际工作的组合。祝你好运:)

<强>更新

另外,我会确保access-control-allow-credentials与其他参数的大小写形式相同。即访问控制允许的凭据。我真的没有任何消息来源,但以防万一:)

我会尝试不使用localhost。使用正确的主机名在不同的服务器上设置测试环境。至少Chrome在本地主机上处理cors时遇到问题。

根据http://www.html5rocks.com/en/tutorials/cors/,请求的内容类型应为以下之一:

  • 应用程序/ x-WWW窗体-urlencoded
  • 的multipart / form-data的
  • 文本/纯

更新2

你可以尝试更多的东西: 添加:

$.support.cors = true;

之前的

$.ajax({ ...

我认为问题可以通过错误的内容类型来解决。 当我对Sharepoint 2013服务器进行CORS设置时,我添加了这个并且一切正常:

headers: { 
  "accept": "application/json;odata=verbose;charset=utf-8",
  "content-type":"application/json;odata=verbose;charset=utf-8"
},

该内容类型可能与您无关,但我可能很重要的是指定。

答案 2 :(得分:0)

您需要在Access-Control-Allow-Origin而不是*中添加请求的域,*可能无法在所有浏览器中使用,因为它存在安全问题 - 即{}中只允许请求的域{1}}请求,而不是*应在选项响应标头中响应。要解决此问题,您需要将该代码更改为以下内容。

OPTIONS

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost");替换为请求的域名,以编程方式执行此操作,您可以使用此功能 - http://localhost

我已在我的博客中更详细地解释了这一点 - BlogCodeProject