пользовательский десериализатор 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.
Спасибо.
1 ответ:
Трудность здесь заключается в том, что a
JavaScriptConverterпозволяет отображать объект JSON из класса c# и в класс c # - но в вашем JSON"xyz"- это просто строка, а не объект. Таким образом, вы не можете указать преобразователь дляsomeOtherDataType, а вместо этого должны указать преобразователи для каждого класса, содержащего экземплярsomeOtherDataType.(Обратите внимание, что функциональность пользовательского конвертера в Json.NET не имеет этого ограничения. Если бы вы захотели переключиться на эту библиотеку, вы могли бы написать
JsonConverterпреобразование всех видов использованияsomeOtherDataTypeиз и в строку JSON.)Написать такое
JavaScriptConverter:
- переопределение
JavaScriptConverter.Deserialize- создайте вторую
Dictionary<string, Object>фильтрацию полей, требующих пользовательского преобразования.- вызов
new JavaScriptSerializer.ConvertToType<T>десериализация стандартных полей из отфильтрованного справочника.- вручную преобразуйте оставшиеся поля.
- переопределение
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