我只花了几个小时调试并查看POSTing JSON to WCF REST Endpoint和Generic WCF JSON Deserialization等问题,但目前我认为我的代码和/或调试在基本级别失败了......
我已经设置了一个WCF服务,如:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, IncludeExceptionDetailInFaults = true)]
public class AutomationService : IAutomationService
{
[WebInvoke(Method = "POST", UriTemplate = "getNextCommand")]
public CommandBase GetNextCommand(int timeoutInMilliseconds)
{
// stuff
}
}
其中IAutomationService是:
[ServiceContract]
public interface IAutomationService
{
[OperationContract]
[ServiceKnownType("GetKnownTypes", typeof(KnownTypeProvider))]
CommandBase GetNextCommand(int timeoutInMilliseconds);
}
我现在已经使用SOAP和JSON端点成功设置了此服务。
然而......我似乎无法解决如何使用Fiddler在ContentBody中传递的变量来调用服务。
例如,我可以在Uri上使用POST调用该服务 - 例如
POST http://localhost:8085/phoneAutomation/jsonAutomate/getNextCommand?timeoutInMilliseconds=10000
但是,如果我尝试将内容放入正文中,那么我会得到一个例外。 e.g。
POST http://localhost:8085/phoneAutomation/jsonAutomate/getNextCommand
Host: localhost:8085
Connection: keep-alive
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1
Accept: application/json,text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: Orchrd-=%7B%22Exp-N42-Settings%22%3A%22open%22%2C%22Exp-N42-New%22%3A%22open%22%7D
Content-Length: 31
Content-Type: application/json
{"timeoutInMilliseconds":10000}
失败了:
服务器在处理请求时遇到错误。例外 消息是'反序列化类型的对象时出错 System.Int32。值''无法解析为'Int32'类型。'。看到 服务器日志了解更多详情。异常堆栈跟踪是:
在 System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader,Boolean verifyObjectName,DataContractResolver dataContractResolver)at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(XmlDictionaryReader 阅读器,布局verifyObjectName)
...
任何人都有任何想法我做错了(除了使用WCF!) - 我只是不确定JSON {“timeoutInMilliseconds”:10000}应该是什么形状。
答案 0 :(得分:1)
默认情况下,WCF REST服务的“正文样式”是“Bare”,这意味着对于具有单个输入的操作,操作的值应该“按原样”,而不包含任何对象。这意味着在你的情况下这将起作用:
POST http://localhost:8085/phoneAutomation/jsonAutomate/getNextCommand
Host: localhost:8085
Connection: keep-alive
Cache-Control: max-age=0
...
Content-Length: 5
Content-Type: application/json
10000
还有一件事,与您的问题没有直接关系:如果您在界面中定义服务合同,您还应该在界面中添加任何“合同相关”属性(例如WebInvoke
)。这将使您的代码看起来像这样:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, IncludeExceptionDetailInFaults = true)]
public class AutomationService : IAutomationService
{
public CommandBase GetNextCommand(int timeoutInMilliseconds)
{
// stuff
}
}
[ServiceContract]
public interface IAutomationService
{
[OperationContract]
[ServiceKnownType("GetKnownTypes", typeof(KnownTypeProvider))]
[WebInvoke(Method = "POST", UriTemplate = "getNextCommand")]
CommandBase GetNextCommand(int timeoutInMilliseconds);
}
另一个信息:如果您想以与原始{"tiemoutInMilliseconds":10000}
)相同的方式发送请求,则可以将BodyStyle
属性中的[WebInvoke]
属性设置为Wrapped(或WrappedRequest):
[ServiceContract]
public interface IAutomationService
{
[OperationContract]
[ServiceKnownType("GetKnownTypes", typeof(KnownTypeProvider))]
[WebInvoke(Method = "POST",
UriTemplate = "getNextCommand",
BodyStyle = WebMessageBodyStyle.WrappedRequest)]
CommandBase GetNextCommand(int timeoutInMilliseconds);
}