开发者

JSON.NET, XmlSerializer and "Specified" property

I have a R开发者_运维问答EST service which takes JSON and XML as input and does a SOAP call to an extenal service with the deserialized content. The classes which are used for deserialization are auto-generated from the wsdl of the SOAP service. I use the XmlSerializer in case of a XML request and I want to use the Newton JSON.NET JsonSerializer for JSON.

Now I have the problem, that the WSDL generated classes contain the "Specified" property for optional atomar values (such as bool, int etc.). This is handled by the XmlSerializer (who sets the property accordingly to the reveived XML) but not by the Newton JSON.NET Serializer. I don't want to force the caller to add the XXXSpecified elements to the JSON string.

How can I treat the "Specified" properties with the JSON.NET serializer?


My solution:

class MyContractResolver : DefaultContractResolver
{
    private JsonObjectContract objectContract = null;

    public override JsonContract ResolveContract(Type type)
    {
        JsonContract contract = base.ResolveContract(type);
        objectContract = contract as JsonObjectContract;
        return contract;
    }

    public void RemoveProperty(string name)
    {
        if (objectContract != null)
        {
            objectContract.Properties.Remove(objectContract.Properties.First(
                 p => p.PropertyName == name));
        }
    }

    public void AtomarOptinalType(string name, bool specified)
    {
        if (objectContract != null)
        {
            if (!specified)
            {
                JsonProperty prop = objectContract.Properties.First(
                     p => p.PropertyName == name);
                objectContract.Properties.Remove(prop);
            }

            RemoveProperty(name + "Specified");
        }
    }
}

and then in extension of the generated classes:

public partial class MyGeneratedClass
{
    [OnDeserializing]
    internal void OnDeserializingMethod(StreamingContext context)
    {
        this.PropertyChanged += 
            new System.ComponentModel.PropertyChangedEventHandler(
                 MyGeneratedClass_PropertyChanged);
    }

    [OnSerializing]
    internal void OnSerializingMethod(StreamingContext context)
    {
        MyContractResolver cr = context.Context as MyContractResolver;

        if (cr != null)
        {
            cr.AtomarOptinalType("MyAtomarOptionalProperty",
                 this.MyAtomarOptionalPropertySpecified);
        }
    }

    void MyGeneratedClass_PropertyChanged(object sender, 
          System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "MyAtomarOptionalProperty")
        {
            this.MyAtomarOptionalPropertySpecified = true;
        }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜