如何将 Json.Net 设置为 WCF REST 服务的默认序列化程序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3118504/
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
How to set Json.Net as the default serializer for WCF REST service
提问by Hossam
Is it possible to override the default WCF DataContractSerializer behaviour when Serialize/DeSerialize entities and use JSON.NET instead?
当序列化/去序列化实体并使用 JSON.NET 时,是否可以覆盖默认的 WCF DataContractSerializer 行为?
I have the following service contract for handling the City entity. For design reasons the City entity has IsReference=true, and therefore the default DataContractSerializer raise errors.
我有以下处理 City 实体的服务合同。出于设计原因,City 实体具有 IsReference=true,因此默认 DataContractSerializer 会引发错误。
For the "GET" methods I can handle the situation with JsonConvert.DeserializeObject, but with "PUT,POST,DELETE" methods DataContractSerializer takes precedence and fails complaining for the IsReference entities cannot be serialized.
对于“GET”方法,我可以使用 JsonConvert.DeserializeObject 处理这种情况,但是使用“PUT、POST、DELETE”方法 DataContractSerializer 优先并且失败,因为 IsReference 实体无法序列化。
I have find this Postto implement IOperationBehavior and provide my own Serializer but I do not know how to integrate Json.NET with this. and I believe there should be more straight forward approach for this.
我找到了这篇文章来实现 IOperationBehavior 并提供我自己的序列化程序,但我不知道如何将 Json.NET 与它集成。我相信应该有更直接的方法来解决这个问题。
I'd appreciate any help or guidance regarding this scenario, or advice to other approaches.
我很感激有关这种情况的任何帮助或指导,或对其他方法的建议。
[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)
{
}
}
Many thanks
非常感谢
Hossam
霍萨姆
采纳答案by Oleg
The usage of Extending Encoders and Serializers (see http://msdn.microsoft.com/en-us/library/ms733092.aspx) or other methods of Extending WCF like usage of DataContractSerializerOperationBehavioris very interesting, but for your special problem there are easier solution ways.
使用扩展编码器和序列化程序(请参阅http://msdn.microsoft.com/en-us/library/ms733092.aspx)或其他扩展 WCF 的方法(如使用DataContractSerializerOperationBehavior)非常有趣,但对于您的特殊问题,则更容易解决办法。
If you already use Messagetype to return the results an use WCF4 you can do something like following:
如果您已经使用Messagetype 返回结果并使用 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);
}
In case of errors (like HttpStatusCode.Unauthorizedor HttpStatusCode.Conflict) or in other situations when you need to set a HTTP status code (like HttpStatusCode.Created) you can continue to use WebOperationContext.Current.OutgoingResponse.StatusCode.
如果出现错误(如HttpStatusCode.Unauthorized或HttpStatusCode.Conflict)或在其他需要设置 HTTP 状态代码(如HttpStatusCode.Created)的情况下,您可以继续使用WebOperationContext.Current.OutgoingResponse.StatusCode.
As an alternative you can also return a Stream(see http://blogs.msdn.com/b/carlosfigueira/archive/2008/04/17/wcf-raw-programming-model-web.aspxand http://msdn.microsoft.com/en-us/library/ms732038.aspx) instead of Messageto return any data without additional default processing by Microsoft JSON serializer. In case of WCF4 you can use CreateStreamResponse(see http://msdn.microsoft.com/en-us/library/dd782273.aspx) instead of CreateTextResponse. Don't forget to set stream position to 0 after writing in the stream if you will use this technique to produce the response.
作为替代方案,您还可以返回一个Stream(参见http://blogs.msdn.com/b/carlosfigeira/archive/2008/04/17/wcf-raw-programming-model-web.aspx和http://msdn。 microsoft.com/en-us/library/ms732038.aspx) 而不是Message返回任何数据,而无需 Microsoft JSON 序列化程序进行额外的默认处理。在 WCF4 的情况下,您可以使用CreateStreamResponse(请参阅http://msdn.microsoft.com/en-us/library/dd782273.aspx)而不是CreateTextResponse. 如果您将使用此技术生成响应,请不要忘记在写入流后将流位置设置为 0。
回答by Steve Michelotti
Is there some reason why you want to use the Json.NET library specifically. If you want to return JSON, why not just use the ResponseFormat property from the WebGet and WebInvoke attributes?
您有什么理由要专门使用 Json.NET 库。如果您想返回 JSON,为什么不直接使用 WebGet 和 WebInvoke 属性中的 ResponseFormat 属性?
[WebGet(UriTemplate = "", ResponseFormat = WebMessageFormat.Json)]
That should for most cases. What version of WCF are you running? Any reason you're returning a Message type rather than the actual type?
这应该适用于大多数情况。您运行的是哪个版本的 WCF?您返回 Message 类型而不是实际类型的任何原因?
回答by Jailson Evora
Define it in your service web config on service behaviors:
在您的服务 web 配置中定义它的服务行为:
<endpointBehaviors>
<behavior name="restfulBehavior">
<webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped" automaticFormatSelectionEnabled="False" />
<!--<enableWebScript />-->
</behavior>
</endpointBehaviors>
or in your operation contract of your Interface
或在您的界面操作合同中
[OperationContract]
[WebInvoke(Method = "GET",
UriTemplate = "/advertisements/{app_id}/{access_token}/{genero}/{age}",
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped)]

