Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
228 views
in Technique[技术] by (71.8m points)

How to set Json.Net as the default serializer for WCF REST service

Is it possible to override the default WCF DataContractSerializer behaviour when Serialize/DeSerialize entities and use JSON.NET instead?

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.

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.

I have find this Post to 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.

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

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 DataContractSerializerOperationBehavior is very interesting, but for your special problem there are easier solution ways.

If you already use Message type to return the results an use WCF4 you can do something like following:

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.Unauthorized or 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.

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.aspx and http://msdn.microsoft.com/en-us/library/ms732038.aspx) instead of Message to 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...