【问题标题】:Error cross domain call using WCF Rest使用 WCF Rest 跨域调用出错
【发布时间】:2015-06-17 22:18:46
【问题描述】:

我正在尝试使用 CORS 调用创建 WCF 服务,到目前为止,我的服务器具有此处指示的类:http://enable-cors.org/server_wcf.html

我能够使用不带任何参数的动词 GET 通过 jQuery ajax 调用进行调用,当我尝试将参数传递给我的请求时出现问题,这是我的代码:

界面标记:

[OperationContract]
[WebInvoke(Method = "*",
           RequestFormat = WebMessageFormat.Json,
           ResponseFormat = WebMessageFormat.Json,
           BodyStyle = WebMessageBodyStyle.WrappedRequest)]
string GetData(TestClass value);

方法标记:

public string GetData(TestClass value)
{
     return value.Id.ToString();
}

js 标记:

var value = { 
    Id : "2", 
    Name: "qwe" 
};

$.ajax({
    url: "http://localhost:38733/Service1.svc/GetData",
    type: "POST",
    contentType: "application/json",
    dataType: "json",
    data: JSON.stringify({ value: value }),
    success: function(result) {
        console.log(result);
    },
    error: function(jqXHR, textStatus, errorThrown) {
        console.log(jqXHR);
    }
});

但是如果我调试,我总是得到 null,这意味着参数没有被传递给方法,我在 Chrome 控制台上也得到了POST http://localhost:38733/Service1.svc/GetData 400 (Bad Request)

我做错了什么?

更新

Web.config 标记:

<behavior name="jsonBehavior">
    <webHttp />
    <crossOriginResourceSharingBehavior />
</behavior>

<extensions>
  <behaviorExtensions>
    <add name="crossOriginResourceSharingBehavior" 
         type="WCFSecureService.EnableCrossOriginResourceSharingBehavior, WCFSecureService, Version=1.0.0.0, Culture=neutral" />
  </behaviorExtensions>
</extensions>

<services>
  <service name="WCFSecureService.Service1">
    <endpoint address="" 
              binding="webHttpBinding" 
              behaviorConfiguration="jsonBehavior" 
              contract="WCFSecureService.IService1" />
  </service>
</services>

在 Google Chrome 控制台上,我得到以下信息:

OPTIONS http://localhost:38733/Service1.svc/GetData?value=5

更新

如果我向没有任何参数的方法发出请求,它会起作用

更新

Fiddler 2 正在向我展示这个,所以我不知道我做错了什么......

更新

TestClass 标记:

[DataContract]
public class TestClass
{
    private int id;
    private string name;

    [DataMember]
    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    [DataMember]
    public int Id
    {
        get { return id; }
        set { id = value; }
    }        
}

更新

如果我使用 JSON.stringify({ value: value })BodyStyle = WebMessageBodyStyle.Bare 我到达服务器,但我得到的所有属性都为 0,请查看下一张图片:

【问题讨论】:

  • 尝试从数据中删除双引号 {"value":5}
  • 只发布您的值,而不是 {value:value} 并显示您的 TestClass 的代码
  • @Strelok 我用TestClass 标记更新了我的问题。我刚刚使用了data: JSON.stringify({ value }),但仍然收到 400(错误请求)
  • @user123456 你非常接近。只需data: JSON.stringify(value)
  • @user123456 并更改为 WebMessageBodyStyle.Bare。查看本教程:codeproject.com/Articles/722874/…

标签: javascript c# jquery ajax wcf


【解决方案1】:

在您的服务合同中,您可能需要添加一个可选的WebGet 指令。

[WebGet(UriTemplate = "GetData/{value}")]
string GetData(int value);

要寻找的另一件事是您在 web.config 中为您的 enpoint 定义了 json 行为。

<endpointBehaviors>
    <behavior name="jsonBehavior">
        <webHttp defaultOutgoingResponseFormat="Json"/>
    </behavior>
    <behavior name="xmlBehavior">
      <webHttp defaultOutgoingResponseFormat="Xml"/>
    </behavior>
</endpointBehaviors>

注意:如果您使用行为,则需要按以下方式指定格式

http://localhost:38733/Service1.svc/json/GetData/5

http://localhost:38733/Service1.svc/xml/GetData/5

另外,你可以试试这个js吗:

var _data= {
    value:5
};

$.ajax({
    ...
    data: _data,
    success: function(data) {
        console.log(data);
    },
    error: function(jqXHR, textStatus, errorThrown) {
        console.log(jqXHR);
    }
});

或者反过来:

$.ajax({
    url: "http://localhost:38733/Service1.svc/json/GetData/5",
});

【讨论】:

  • 但是使用WebGet 我将无法使用其他方法,例如POSTjs 更改也不起作用。我已经用我的web.config 的行为更新了我的答案。谢谢!
  • 如果我尝试在WebGet 上使用UriTemplate,我会收到以下错误:Operation 'GetData' in contract 'IService1' has a path variable named 'value' which does not have type 'string'
  • 在 wcf 中有很多种打包、信封、传输、序列化、反序列化的方法。您必须找到适用于您的 api 的组合。对不起,我没有太多帮助。
  • 别担心,谢谢帮助,如果您有任何其他想法,请随时告诉它,我对这个错误有点沮丧。
【解决方案2】:

我找到了适合我的情况的解决方案。最后这是一个测试,所以我将使用更多的参数,所以这是我学到的:

  • 对于多个参数,请求必须被包装,所以, WebInvoke 的合约注释必须是 BodyStyle = WebMessageBodyStyle.WrappedRequest
  • 在客户端,只要一个参数,使用JSON.stringify(value)就可以了,但不止一个,你必须更具体,例如:

    data: JSON.stringify({
        value: value, 
        text: "any text"
    });
    
  • 在我提供的关于我的问题的链接中,我必须包含两个类 CustomHeaderMessageInspectorEnableCrossOriginResourceSharingBehavior,好像是 如果您可以使用 global.asax 文件,则不再需要,您 只需将以下代码添加到 Application_BeginRequest

    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    {
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE, GET");
    
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
        HttpContext.Current.Response.End();
    }
    

我的web.config 是这样结束的:

<bindings>
  <webHttpBinding>
    <binding name="Binding" crossDomainScriptAccessEnabled="true">
      <security mode="Transport">
        <transport clientCredentialType="None" />
      </security>
    </binding>
    <binding name="corsBinding" crossDomainScriptAccessEnabled="true" />
  </webHttpBinding>
</bindings>

<services>
  <service name="WCFSecureService.Service1" behaviorConfiguration="ServiceBehaviour">
    <endpoint address="bs" binding="basicHttpBinding" contract="WCFSecureService.IService1" />
    <endpoint address="" 
              binding="webHttpBinding"
              bindingConfiguration="corsBinding"
              behaviorConfiguration="jsonBehavior"
              contract="WCFSecureService.IService1" />
  </service>
</services>

<behaviors>
  <serviceBehaviors>
    <behavior name="ServiceBehaviour">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
    <behavior name="jsonBehavior">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>

  <endpointBehaviors>        
    <behavior name="jsonBehavior">
      <webHttp helpEnabled="true" />
    </behavior>
  </endpointBehaviors>
</behaviors>

感谢您的帮助,我希望它可以帮助其他人。

【讨论】:

    猜你喜欢
    • 2014-01-13
    • 2011-10-05
    • 2011-04-13
    • 2023-03-31
    • 1970-01-01
    • 2013-12-27
    • 2014-10-08
    • 2012-03-07
    • 2011-10-15
    相关资源
    最近更新 更多