签订合同:
namespace ACME.FooServices
{
[ServiceContract]
public interface IFooService
{
[OperationContract]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare)]
FooMessageType Foo(string name);
}
[DataContract]
public class FooMessageType
{
string _name;
string _date;
[DataMember]
public string Name
{
get { return _name; }
set { _name = value; }
}
[DataMember]
public string Date
{
get { return _date; }
set { _date = value; }
}
}
}
并实施:
using System;
using System.ServiceModel.Activation;
namespace ACME.FooServices
{
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class FooService : IFooService
{
public FooMessageType Foo(string name)
{
string l_name = (String.IsNullOrWhiteSpace(name)) ? "Anonymous" : name;
return new FooMessageType {Name = l_name, Date = DateTime.Now.ToString("MM-dd-yyyy h:mm:ss tt")};
}
}
}
在web.config中配置为:
<system.serviceModel>
<services>
<service name="ACME.FooServices.FooService">
<endpoint address="" behaviorConfiguration="ACME.FooBehaviour" binding="webHttpBinding" contract="ACME.FooServices.IFooService" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="ACME.FooBehaviour">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
我试图通过jQuery从页面调用Foo:
<script type="text/javascript" language="javascript">
$(document).ready(function () {
$("#msgButton").click(function () {
var params = {};
params.name = $("#nameTextbox").val();
$.ajax({
type: 'POST',
url: "http://acme.com/wcfsvc/FooService.svc/Foo",
data: JSON.stringify(params),
contentType: 'application/json; charset=utf-8',
success: function (response, status, xhr) { alert('success: ' + response); },
error: function (xhr, status, error) { alert("Error\n-----\n" + xhr.status + '\n' + xhr.responseText); },
complete: function (jqXHR, status) { alert('Status: ' + status + '\njqXHR: ' + JSON.stringify(jqXHR)); }
});
});
});
</script>
但是我收到 400 - 错误请求错误消息“服务器在处理请求时遇到错误。异常消息是'反序列化对象时出错类型System.String。结束元素'root'来自命名空间''expected。找到元素'name'来自命名空间“。
我错过了什么吗?
答案 0 :(得分:15)
您的params
是对象,它形成{ "name" : "someValue" }
JSON字符串。如果您说邮件正文样式为Bare
,我认为您的服务需要这样的内容:
[DataContract]
public class SomeDTO
{
[DataMember(Name = "name")]
public string Name { get; set; }
}
因此,您的操作应定义为:
[OperationContract]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare)]
FooMessageType Foo(SomeDTO data);
如果您希望当前的代码正常工作,您应该将其更改为:
[OperationContract]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest)]
FooMessageType Foo(SomeDTO data);
答案 1 :(得分:6)
我遇到了同样的问题。设置 BodyStyle = WebMessageBodyStyle.Wrapped 后,它解决了。
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
答案 2 :(得分:4)
尝试设置BodyStyle=WebMessageBodyStyle.Wrapped
答案 3 :(得分:0)
BodyStyle = WebMessageBodyStyle.WrappedRequest对我有用,如果你是来自fiddler或其他其他客户请求 但是如果你从HTTPWebResponse请求Bare将会工作