WCF - 将JSON发布到端点 - 请求内容主体应该是什么样的?

时间:2011-10-19 17:20:56

标签: wcf json fiddler

我只花了几个小时调试并查看POSTing JSON to WCF REST EndpointGeneric 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}应该是什么形状。

1 个答案:

答案 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);
}