首页 文章

如何将Json.Net设置为WCF REST服务的默认序列化程序

提问于
浏览
21

在Serialize / DeSerialize实体并使用JSON.NET时,是否可以覆盖默认的WCF DataContractSerializer行为?

我有以下服务 Contract 来处理City实体 . 出于设计原因,City实体具有IsReference = true,因此默认的DataContractSerializer会引发错误 .

对于“GET”方法,我可以使用JsonConvert.DeserializeObject处理这种情况,但是使用“PUT,POST,DELETE”方法DataContractSerializer优先,并且失败抱怨IsReference实体无法序列化 .

我发现这个Post实现IOperationBehavior并提供我自己的Serializer但我不知道如何将Json.NET与此集成 . 而且我认为应该有更直接的方法 .

我很感激有关此方案的任何帮助或指导,或对其他方法的建议 .

[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class CityService
{
    [Description("Get all Cities")]  
    [WebGet(UriTemplate = "")]
    public Message Cities()
    {

    }

    [Description("Allows the details of a single City to be updated.")]
    [WebInvoke(UriTemplate = "{code}", Method = "PUT")]
    public Message UpdateCity(string code, City city)
    {
    }
}

非常感谢

霍山

3 回答

  • 21

    使用扩展编码器和序列化器(参见http://msdn.microsoft.com/en-us/library/ms733092.aspx)或扩展WCF的其他方法(例如 DataContractSerializerOperationBehavior 的使用)非常有趣,但对于您的特殊问题,有更简单的解决方法 .

    如果您已经使用 Message 类型返回结果,请使用WCF4,您可以执行以下操作:

    public Message UpdateCity(string code, City city)
    {
        MyResponseDataClass message = CreateMyResponse();
        // use JSON.NET to serialize the response data
        string myResponseBody = JsonConvert.Serialize(message);
        return WebOperationContext.Current.CreateTextResponse (myResponseBody,
                    "application/json; charset=utf-8",
                    Encoding.UTF8);
    }
    

    如果出现错误(如 HttpStatusCode.UnauthorizedHttpStatusCode.Conflict )或在需要设置HTTP状态代码(如 HttpStatusCode.Created )的其他情况下,您可以继续使用 WebOperationContext.Current.OutgoingResponse.StatusCode .

    作为替代方法,您还可以返回 Stream (请参阅http://blogs.msdn.com/b/carlosfigueira/archive/2008/04/17/wcf-raw-programming-model-web.aspxhttp://msdn.microsoft.com/en-us/library/ms732038.aspx)而不是 Message 以返回任何数据,而无需Microsoft JSON序列化程序的其他默认处理 . 对于WCF4,您可以使用 CreateStreamResponse (参见http://msdn.microsoft.com/en-us/library/dd782273.aspx)而不是 CreateTextResponse . 如果您将使用此技术生成响应,请不要忘记在流中写入后将流位置设置为0 .

  • 1

    您是否有理由特别要使用Json.NET库?如果要返回JSON,为什么不直接使用WebGet和WebInvoke属性中的ResponseFormat属性?

    [WebGet(UriTemplate = "", ResponseFormat = WebMessageFormat.Json)]
    

    在大多数情况下应该如此 . 你在运行什么版本的WCF?您是否返回Message类型而不是实际类型?

  • 0

    在服务Web配置中定义服务行为:

    <endpointBehaviors>
       <behavior name="restfulBehavior">
          <webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped" automaticFormatSelectionEnabled="False" />
          <!--<enableWebScript />-->
       </behavior>
    </endpointBehaviors>
    

    或者在您的界面的操作 Contract 中

    [OperationContract]
    [WebInvoke(Method = "GET", 
               UriTemplate = "/advertisements/{app_id}/{access_token}/{genero}/{age}", 
               ResponseFormat = WebMessageFormat.Json,
               RequestFormat = WebMessageFormat.Json, 
               BodyStyle = WebMessageBodyStyle.Wrapped)]
    

相关问题