json - custom javascript deserializer in c# -
i working on c# application has browser integrated it. browser send data c# in json format.
some of fields json can dserialized using javascript deserializer, have data custom deserializer required, need register deserializer thing custom deserializer must called special data , default javascript deserializer must called other data, special data can identified there target field's data type / name in c#. how can achieve this.
something this.
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 } }
the json string
{ "abc" : "valueabc" "xyz" : "valuexyz" }
now custom deserializer must called during deserializing xyz , default must called abc.
thank you.
the difficulty here javascriptconverter
allows map json object , c# class -- in json, "xyz"
string, not object. can't specify converter someotherdatatype
, instead must specify converters every class contains instance of someotherdatatype
.
(note custom converter functionality in json.net not have restriction. if willing switch library write jsonconverter
converting uses of someotherdatatype
, json string.)
to write such javascriptconverter
:
- override
javascriptconverter.deserialize
- create second
dictionary<string, object>
filtering out fields requiring custom conversion. - call
new javascriptserializer.converttotype<t>
deserialize standard fields filtered dictionary. - manually convert remaining fields.
- override
supportedtypes
return container type.
thus, in example, do:
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 string) { return new someotherdatatype { someproperty = (string)xyzvalue }; } return null; } } class exampleconverter : javascriptconverter { public override ienumerable<type> supportedtypes { { 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 "fresh" javascriptserializer here 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(); } }
and then, test:
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
Post a Comment