【问题标题】:wcf REST Services and JQuery Ajax Post: Method not allowedwcf REST 服务和 JQuery Ajax Post:方法不允许
【发布时间】:2011-10-01 19:06:53
【问题描述】:

有人知道这是怎么回事吗?我无法从我的 wcf 休息服务获得 json 响应。

jQuery

$.ajax({ type: 'POST', url: "http://localhost:8090/UserService/ValidateUser", data: {username: 'newuser', password: 'pwd'}, contentType: "application/json; charset=utf-8", success: function(msg) { alert(msg); }, error: function(xhr, ajaxOptions, thrownError) { alert('error'); } });

服务

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] public class UserService: IUserService { private readonly IUserRepository _repository; public UserService() { _repository = new UserRepository(); } public ServiceObject ValidateUser(string username, string password) { //implementation } } [ServiceContract] public interface IUserService { [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)] [OperationContract] ServiceObject ValidateUser(string username, string password); }

网络配置

<system.serviceModel> <!--Behaviors here.--> <behaviors> <endpointBehaviors> <behavior name="defaultEndpointBehavior"> <webHttp/> </behavior> </endpointBehaviors> <serviceBehaviors> <behavior name=""> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors> <!--End of Behaviors--> <!--Services here--> <services> <service name="MyWcf.Services.UserService"> <endpoint address="UserService" behaviorConfiguration="defaultEndpointBehavior" binding="webHttpBinding" contract="MyWcf.Services.IUserService" /> </service> </services> <!--End of Services--> <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> <standardEndpoints> <webHttpEndpoint> <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" defaultOutgoingResponseFormat ="Json" crossDomainScriptAccessEnabled="true"/> </webHttpEndpoint> </standardEndpoints> </system.serviceModel>

【问题讨论】:

    标签: jquery ajax wcf json wcf-rest


    【解决方案1】:

    我在您的代码中发现了多个问题:

    405 表示方法不允许 - 这可能意味着您将数据发布到错误的资源。你确定你的地址是正确的吗?你如何公开服务?是.svc 文件还是ServiceRoute?如果是.svc 文件地址将是UserService.svc/UserService/ValidateUser

    • UserService.svc,因为这是您的服务的入口点(如果您使用的是ServiceRoute,您可以重新定义它
    • UserService,因为您在端点配置中定义了这个相对地址
    • ValidateUser 因为这是您操作的默认入口点

    现在您的 JSON 请求完全错误,您的方法签名也是如此。服务合约中的方法签名必须期望单个 JSON 对象 = 它必须是单个数据合约,例如:

    [DataContract]
    public class UserData
    {
        [DataMember]
        public string UserName { get; set; }
    
        [DataMember]
        public string Password { get; set; }
    }
    

    操作签名为:

    [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare)]
    [OperationContract]
    ServiceObject ValidateUser(UserData userData);
    

    JSON 请求中没有包装器元素,因此您必须使用Bare。此外,不需要设置响应格式,因为您将在端点级别设置它(顺便说一句。如果不这样做,您还必须设置请求格式)。

    为请求定义数据协定后,您必须正确定义 ajax 请求本身:

    $.ajax({
      type: 'POST',
      url: "UserService.svc/UserService/ValidateUser",
      data: '{"UserName":"newuser","Password":"pwd"}',
      contentType: "application/json; charset=utf-8", 
      success: function (msg) {
        alert(msg);
      },
    
      error: function (xhr, ajaxOptions, thrownError) {
        alert('error');
      }
    
    });
    

    JSON 对象是字符串!以及它的所有成员!

    最后将您的配置修改为:

    <system.serviceModel>
      <services>
        <service name="UserService.UserService">
          <endpoint address="UserService" kind="webHttpEndpoint" contract="UserService.IUserService" />
        </service>
      </services>
      <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
      <standardEndpoints>
        <webHttpEndpoint>
          <standardEndpoint helpEnabled="true" automaticFormatSelectionEnabled="true" />
        </webHttpEndpoint>
      </standardEndpoints>
    </system.serviceModel>
    

    如果您想使用standardEndpoint,您必须在端点定义中使用kind,并且您不需要指定行为(它是标准端点的一部分)。此外,您没有使用跨域调用,因此您不需要启用它们,也不需要默认格式,因为它是自动解析的。

    【讨论】:

    • 我按照您的修改进行了尝试,当我尝试它时,它说:合同“IUserService”的操作“ValidateUser”指定了多个要序列化的请求主体参数,而无需任何包装器元素。最多一个 body 参数可以在没有包装元素的情况下被序列化。删除额外的正文参数或将 WebGetAttribute/WebInvokeAttribute 上的 BodyStyle 属性设置为 Wrapped。
    • 所以你没有按照我的修改,因为我的ValidateUser 没有多个请求正文参数。
    • 我已将参数更改为 UserData,当我运行它时,“方法不允许”。在 Global.asax,我把 ff 和它的作品: HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin","*"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods","GET, POST"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers","Content-Type, Accept"); HttpContext.Current.Response.End();
    • 有没有办法在 Global.asax 上不做任何事情就将数据发布到服务中?
    • 是的,有一种方法,因为我已经使用 jquery 测试了我用 .aspx 页面描述的更改以及托管在我的本地 IIS 上的页面和服务,它可以正常工作,也不需要修改标题。
    【解决方案2】:

    我相信 Ivan 在这里是正确的!

    您是在浏览器中从 javascript 调用您的服务,对吧?

    带有该 javascript 的 html 页面是否与 wcf 服务位于同一域中?

    如果他们不在同一个域中,那么我会说这是一个跨站点脚本问题。我相信 GET 允许跨站点,但 POST 不允许。 http://en.wikipedia.org/wiki/JSONP 将是一个解决方案,如果它受服务器端支持(由 WCF)

    【讨论】:

    • 您提到跨域 WCF REST JQuery Ajax 调用中不允许使用 POST。你能给我它的来源吗?因为,仅从您的帖子中我了解到跨域不支持 POST。出于安全考虑,我想使用 POST,但它不起作用。
    • en.wikipedia.org/wiki/Same_origin_policy 解释得很好,但如果您正在寻找答案,您可以在 SO 上找到一些建议,例如stackoverflow.com/questions/298745/…
    【解决方案3】:

    您在一个域上进行了测试,我想作者尝试从不同的域进行调用。由于跨域调用,这可能是不可能的。

    【讨论】:

      猜你喜欢
      • 2012-04-21
      • 2015-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-17
      • 2012-06-11
      • 2014-03-30
      • 2011-03-04
      相关资源
      最近更新 更多