пользовательский десериализатор javascript в c#



Я работаю над приложением на языке C#, в которое встроен браузер.
Браузер будет отправлять некоторые данные на C# в формате json.



Некоторые поля из JSON может быть dserialized на JavaScript десериализатор, но у меня есть некоторые данные, для которых пользовательский десериализатор не требуется, мне нужно зарегистрировать десериализатор, но дело в том, что пользовательский десериализатор должен быть вызван только для тех специальных данных и по умолчанию JavaScript десериализатор должен быть призван для других данных специальные данные могут быть идентифицированы оттуда типом данных / именем целевого поля в C#. Как я могу этого достичь?



Что-то вроде этого.



public class example
{
public string abc;
public someOtherDataType xyz;

public void example()
{
serializer = new JavaScriptSerializer();

// receive json string

serializer.RegisterConverters(new JavaScriptConverter[]
{
new System.Web.Script.Serialization.CS.CustomConverter()
});

//call deserializer

}
}


Строка json будет иметь вид



{
"abc" : "valueabc"
"xyz" : "valueXYZ"
}


Теперь пользовательский десериализатор должен вызываться только во время десериализации xyz, а значение по умолчанию должно вызываться для abc.



Спасибо.

631   1  

1 ответ:

Трудность здесь заключается в том, что a JavaScriptConverter позволяет отображать объект JSON из класса c# и в класс c # - но в вашем JSON "xyz" - это просто строка, а не объект. Таким образом, вы не можете указать преобразователь для someOtherDataType, а вместо этого должны указать преобразователи для каждого класса, содержащего экземпляр someOtherDataType.

(Обратите внимание, что функциональность пользовательского конвертера в Json.NET не имеет этого ограничения. Если бы вы захотели переключиться на эту библиотеку, вы могли бы написать JsonConverter преобразование всех видов использования someOtherDataType из и в строку JSON.)

Написать такое JavaScriptConverter:

  1. переопределение JavaScriptConverter.Deserialize
  2. создайте вторую Dictionary<string, Object> фильтрацию полей, требующих пользовательского преобразования.
  3. вызов new JavaScriptSerializer.ConvertToType<T> десериализация стандартных полей из отфильтрованного справочника.
  4. вручную преобразуйте оставшиеся поля.
  5. переопределение SupportedTypes чтобы вернуть тип контейнера.

Таким образом, в ваш пример, вы могли бы сделать:

public class example
{
    public string abc;
    public someOtherDataType xyz;
}

// Example implementation only.
public class someOtherDataType
{
    public string SomeProperty { get; set; }

    public static someOtherDataType CreateFromJsonObject(object xyzValue)
    {
        if (xyzValue is string)
        {
            return new someOtherDataType { SomeProperty = (string)xyzValue };
        }
        return null;
    }
}

class exampleConverter : JavaScriptConverter
{
    public override IEnumerable<Type> SupportedTypes
    {
        get { return new[] { typeof(example) }; }
    }

    // Custom conversion code below

    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        var defaultDict = dictionary.Where(pair => pair.Key != "xyz").ToDictionary(pair => pair.Key, pair => pair.Value);
        var overrideDict = dictionary.Where(pair => !(pair.Key != "xyz")).ToDictionary(pair => pair.Key, pair => pair.Value);

        // Use a "fresh" JavaScriptSerializer here to avoid infinite recursion.
        var value = (example)new JavaScriptSerializer().ConvertToType<example>(defaultDict);

        object xyzValue;
        if (overrideDict.TryGetValue("xyz", out xyzValue))
        {
            value.xyz = someOtherDataType.CreateFromJsonObject(xyzValue);
        }
        return value;
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

И затем, чтобы проверить:

public class TestClass
{
    public static void Test()
    {
        // receive json string
        string json = @"{
""abc"" : ""valueabc"",
""xyz"" : ""valueXYZ""
}";
        var serializer = new JavaScriptSerializer();
        serializer.RegisterConverters(new JavaScriptConverter[]
         { 
             new exampleConverter()
         });

        var example = serializer.Deserialize<example>(json);
        Debug.Assert(example.abc == "valueabc" && example.xyz.SomeProperty == "valueXYZ"); // No assert
    }
}

Comments

    Ничего не найдено.