c#中的自定义JavaScript解串器#

问题描述:

我正在研究一个与浏览器集成的C#应用​​程序。 浏览器将以json格式向C#发送一些数据。c#中的自定义JavaScript解串器#

json的一些字段可以使用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。

谢谢。

+0

是什么让这两个对象有什么不同?如何在反序列化之前将它们分开?你有没有反序列化的C#类(如果有的话,你可以发布它)吗? – br4d

+0

是的,我确实有一堂课,就像dbc的答案一样。 – Anurag

这里的难点在于JavaScriptConverter允许你将一个JSON对象映射到一个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 
    } 
} 
+1

感谢dbc,它对我的​​应用程序使用此解决方案工作良好。 – Anurag