JSON.NET, XmlSerializer и свойство «Указанный» - PullRequest
1 голос
/ 01 сентября 2010

У меня есть служба REST, которая принимает JSON и XML в качестве входных данных и выполняет SOAP-вызов к внешней службе с десериализованным содержимым. Классы, которые используются для десериализации, генерируются автоматически из wsdl службы SOAP. Я использую XmlSerializer в случае запроса XML и хочу использовать JSON.NET JsonSerializer Ньютона для JSON.

Теперь у меня проблема в том, что сгенерированные WSDL классы содержат свойство "Specified" для необязательных значений atomar (таких как bool, int и т. Д.). Это обрабатывается XmlSerializer (который устанавливает свойство в соответствии с полученным XML), но не Newton JSON.NET Serializer. Я не хочу заставлять вызывающую сторону добавлять элементы XXXSpecified в строку JSON.

Как я могу обработать "Указанные" свойства с помощью сериализатора JSON.NET?

1 Ответ

0 голосов
/ 03 сентября 2010

Мое решение:

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");
        }
    }
}

, а затем в расширении сгенерированных классов:

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;
        }
    }
}
...