如何将Json.Net设置为WCF REST服务的默认序列化程序
在序列化/反序列化实体并使用JSON.NET时,是否可以覆盖默认的WCF DataContractSerializer行为 我有以下处理城市实体的服务合同。出于设计原因,城市实体的IsReference=true,因此默认的DataContractSerializer会引发错误 对于“GET”方法,我可以使用JsonConvert.DeserializeObject处理这种情况,但对于“PUT、POST、DELETE”方法,DataContractSerializer优先,并且无法序列化IsReference实体 我发现这是为了实现IOperationBehavior并提供我自己的序列化程序,但我不知道如何将Json.NET与此集成。我认为应该有更直接的方法来解决这个问题 我非常感谢任何关于这个场景的帮助或指导,或者对其他方法的建议如何将Json.Net设置为WCF REST服务的默认序列化程序,wcf,json,rest,.net-4.0,json.net,Wcf,Json,Rest,.net 4.0,Json.net,在序列化/反序列化实体并使用JSON.NET时,是否可以覆盖默认的WCF DataContractSerializer行为 我有以下处理城市实体的服务合同。出于设计原因,城市实体的IsReference=true,因此默认的DataContractSerializer会引发错误 对于“GET”方法,我可以使用JsonConvert.DeserializeObject处理这种情况,但对于“PUT、POST、DELETE”方法,DataContractSerializer优先,并且无法序列化IsRe
[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)
{
}
}
非常感谢
Hossam您为什么要专门使用Json.NET库。如果要返回JSON,为什么不使用WebGet和WebInvoke属性中的ResponseFormat属性呢
[WebGet(UriTemplate = "", ResponseFormat = WebMessageFormat.Json)]
在大多数情况下,这应该是正确的。您正在运行哪个版本的WCF?返回消息类型而不是实际类型的原因是什么?使用扩展编码器和序列化器(请参阅)或其他扩展WCF的方法(如使用
DataContractSerializerOperationBehavior
非常有趣,但对于您的特殊问题,有更简单的解决方法
如果您已经使用Message
type返回结果,则可以使用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.Unauthorized
或HttpStatusCode.Conflict
),或者在需要设置HTTP状态代码的其他情况下(如HttpStatusCode.Created
),您可以继续使用WebOperationContext.Current.OutgoingResponse.StatusCode
)
或者,您也可以返回
流
(请参阅和),而不是消息
,以返回任何数据,而无需Microsoft JSON序列化程序进行额外的默认处理。对于WCF4,您可以使用CreateStreamResponse
(请参阅)而不是CreateTextResponse
。如果要使用此技术生成响应,请不要忘记在写入流后将流位置设置为0。在服务行为的服务web配置中定义它:
<endpointBehaviors>
<behavior name="restfulBehavior">
<webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped" automaticFormatSelectionEnabled="False" />
<!--<enableWebScript />-->
</behavior>
</endpointBehaviors>
是WCF4。在我的web.config中,我有defaultOutgoingResponseFormat=“Json”,因此我不必修饰服务方法。根据设计,我的所有实体都具有[IsReference=true],无法使用默认DataContractSerializer进行序列化。所以我必须使用另一个序列化程序,比如Json.net,它可以处理具有[IsReference=true]的实体。我返回的消息类型不会让我的响应序列化两次,一次是json.net,然后是DataContractSerializer。如果我返回实际类型,我会得到无效的json,比如“{\“City\”:“Cairo\”}”Thanx作为您的回复。因此,如果您不使用IsReference属性,但由于另一个原因必须通过设计来使用它,这对您是有效的?正确的,IsReference是唯一的问题。这在许多帖子中都有报道,DataContractJsonSerializer无法序列化标记为IsReference=true的实体。这就是为什么我希望使用另一个序列化程序。许多人感谢默认的JSON序列化程序缺乏对嵌入和恢复类型信息、保留对象引用和允许自引用循环的任何支持。JSON.NET通过包含$type、$id和$ref属性来很好地处理它们。DataContractJsonSerializer的DateTime序列化也非常糟糕。这如何处理对传入城市对象的反序列化?@Christopher Stott:请参阅以“读取消息”开头的示例。从该链接,看起来UpdateCity必须采用消息参数才能使用JSON.NET进行反序列化。对吗?有什么办法吗?我知道它很旧,但用TimeSpan和DateTime格式解决了我的问题。@ramires.cabral:这是个好消息!顺便说一下,使用
JSON.NET
(Newtonsoft.JSON
)可以设置转换过程中使用的一些附加选项:作为jsonvert.SerializeObject
的第二/第三个参数和格式化.Indented
。我个人最喜欢将ContractResolver
与new CamelCasePropertyNamesContractResolver()
一起使用,将NullValueHandling
与NullValueHandling一起使用?传入的请求是json,需要在C#PascalCase类中序列化吗?请看我的帖子:
[OperationContract]
[WebInvoke(Method = "GET",
UriTemplate = "/advertisements/{app_id}/{access_token}/{genero}/{age}",
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped)]