wcf REST 服务和 JQuery Ajax Post:方法不允许
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6633648/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
wcf REST Services and JQuery Ajax Post: Method not allowed
提问by h3n
Anyone knows what's wrong with this? I cant get the json response from my wcf rest service.
有谁知道这有什么问题?我无法从我的 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');
}
});
Service
服务
[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>
回答by Ladislav Mrnka
I see multiple problems in your code:
我在您的代码中看到多个问题:
405 means method not allowed - it can mean that you are posting data to wrong resource. Are you sure that your address is correct? How do you expose the service? Is it .svc
file or ServiceRoute
? If it is .svc
file the address will be UserService.svc/UserService/ValidateUser
405 表示方法不允许 - 这可能意味着您将数据发布到错误的资源。你确定你的地址是正确的吗?你如何公开服务?是.svc
文件还是ServiceRoute
?如果是.svc
文件,地址将是UserService.svc/UserService/ValidateUser
- UserService.svc because this is entry point for your service (if you are using
ServiceRoute
you can redefine this - UserService because you are defining this relative address in endpoint configuration
- ValidateUser because that is default entry point for your operation
- UserService.svc 因为这是您的服务的入口点(如果您正在使用,
ServiceRoute
您可以重新定义它 - UserService 因为您正在端点配置中定义此相对地址
- ValidateUser 因为这是您操作的默认入口点
Now your JSON request is completely bad and your method signature as well. Method signature in your service contract must expect single JSON object = it must be single data contract like:
现在您的 JSON 请求完全错误,您的方法签名也是如此。您的服务合同中的方法签名必须期望单个 JSON 对象 = 它必须是单个数据合同,例如:
[DataContract]
public class UserData
{
[DataMember]
public string UserName { get; set; }
[DataMember]
public string Password { get; set; }
}
and operation signature will be:
和操作签名将是:
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare)]
[OperationContract]
ServiceObject ValidateUser(UserData userData);
There is no wrapper element in JSON request and because of that you must use Bare
. Also it is not needed to set response format because you will set it on endpoint level (btw. you must also set request format if you don't).
JSON 请求中没有包装器元素,因此您必须使用Bare
. 此外,不需要设置响应格式,因为您将在端点级别设置它(顺便说一句。如果不这样做,您还必须设置请求格式)。
Once you defined data contract for your request you must correctly define ajax request itself:
为请求定义数据契约后,您必须正确定义 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 object is as string! and all its members as well!
JSON 对象是字符串!以及它的所有成员!
For last modify your configuration to:
最后将您的配置修改为:
<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>
If you want to use standardEndpoint
you must use kind
in endpoint definition and you don't need to specify behavior (it is part of standard endpoint). Also you are not using cross domain calls so you don't need to enable them and you don't need default format because it is resolved automatically.
如果要使用standardEndpoint
,则必须kind
在端点定义中使用,并且不需要指定行为(它是标准端点的一部分)。此外,您没有使用跨域调用,因此您不需要启用它们,也不需要默认格式,因为它会自动解析。
回答by Joakim
I believe Ivan is on the right track here!
我相信伊万在这里走在正确的轨道上!
You are calling your service from javascript in a browser, right?
您是在浏览器中从 javascript 调用您的服务,对吗?
Does the html page with that javascript reside in the same domain as the wcf service?
带有该 javascript 的 html 页面是否与 wcf 服务位于同一域中?
If they are not in the same domain, then I would say that it is a cross-site-scriptingissue. I believe GET is allowed cross-sites, but POST are not. http://en.wikipedia.org/wiki/JSONPwould be a solution, if it's supported server-side (by WCF)
如果它们不在同一个域中,那么我会说这是一个跨站点脚本问题。我相信 GET 允许跨站点,但 POST 不允许。http://en.wikipedia.org/wiki/JSONP将是一个解决方案,如果它支持服务器端(由 WCF)
回答by Ivan
You tested on one domain I suppose the author try to make call from different domain. It could be impossible due to cross domain calls.
您在一个域上进行了测试,我想作者尝试从不同的域拨打电话。由于跨域调用,这可能是不可能的。