wcf REST服务和JQuery Ajax Post:不允许使用方法

时间:2011-07-09 08:25:12

标签: jquery ajax wcf json wcf-rest

任何人都知道这有什么问题吗?我无法从我的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);
    }


web config



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


3 个答案:

答案 0 :(得分:9)

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

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,并且不需要指定行为(它是标准端点的一部分)。此外,您不使用跨域调用,因此您不需要启用它们,并且您不需要默认格式,因为它会自动解决。

答案 1 :(得分:2)

我相信伊万在这里走在正确的轨道上!

您是在浏览器中使用javascript调用服务,对吗?

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

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

答案 2 :(得分:1)

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