Po dlouhé době jsem narazil na zajímavý problém. Potřebuji uložit data do formátu JSON ale každá datová položka je jiný typ. Jedná se o tzv. polymofní typ. Například chci si uložit databázi zvířat (animals) a mám definovaný obecný objekt animal a pak mám definované konkrétní typy Cat, Lion, Horse. A každý typ má trochu jiné vlastnosti.
Podívejme se na můj konkrétní případ: Mám pole nějakých objektů, které představují nějaké nastavení. Každá položka v poli má své jméno Name a hodnotu Value.
public class OptionValue { [DataMember] public string Name { get; set; } [DataMember] public object Value { get; set; } }
[DataContract] public class IntValue { public IntValue() { } public IntValue(string name) { Name = name; } [DataMember] public string Name { get; set; } [DataMember] public new Int32 Value { get; set; } } [DataContract] public class BoolValue { public BoolValue() { } public BoolValue(string name) { Name = name; } [DataMember] public string Name { get; set; } [DataMember] public new bool Value { get; set; } } [DataContract] public class StringValue { public StringValue() { } public StringValue(string name) { Name = name; } [DataMember] public string Name { get; set; } [DataMember] public new String Value { get; set; } } [DataContract] public class TimeValue { public TimeValue() { } public TimeValue(string name) { Name = name; } [DataMember] public string Name { get; set; } [DataMember] public new TimeSpan Value { get; set; } } [DataContract] public class DateValue { public DateValue() { } public DateValue(string name) { Name = name; } [DataMember] public string Name { get; set; } [DataMember] public new DateTime Value { get; set; } }
msg = Request.CreateResponse(HttpStatusCode.OK,array, "application/json");
dostanu výsledek, kde nevím, jakého typu mám položky.
[{"Name":"DefaultSection","Value":"SatelliteHolder"},{"Name":"FillInterfaceName","Value":"Bonus"},{"Name":"FillFilterName","Value":"SATELLITE FILL"},{"Name":"FillSection:Position","Value":"end"},{"Name":"FillSection:Position","Value":"end"},{"Name":"FillSection:Position","Value":"end"},{"Name":"ConfigFillSectionType","Value":"SpotsetHolder"},{"Name":"MinAllowFillDistance","Value":240},{"Name":"MinGroupFillDistance","Value":10},{"Name":"SeparationFilterName","Value":"SATELLITE SEPARATION"},{"Name":"FillFilterSkip","Value":"SATELLITE SKIP"},{"Name":"ConfigSkipSectionType","Value":"SpotsetHolder"},{"Name":"Performance","Value":false},{"Name":"VisibleSections","Value":"HourHeader|SatelliteHolder"}]
string json = new JavaScriptSerializer(new TypeResolver()).Serialize(o); msg = Request.CreateResponse(HttpStatusCode.OK,json, "application/json");
public class TypeResolver : JavaScriptTypeResolver { public override Type ResolveType(string id) { if (id == "string") { return new StringValue().GetType(); } else if (id == "int") { return new IntValue().GetType(); } else if (id == "bool") { return new BoolValue().GetType(); } else if (id == "float") { return new FloatValue().GetType(); } else if (id == "time") { return new TimeSpan().GetType(); } else if (id == "date") { return new DateTime().GetType(); } return new object().GetType(); } public override string ResolveTypeId(Type type) { if (type.Name == "StringValue") return "string"; else if (type.Name == "IntValue") return "int"; else if (type.Name == "BoolValue") return "bool"; else if (type.Name == "FloatValue") return "float"; else if (type.Name == "TimeValue") return "time"; else if (type.Name == "DateValue") return "date"; return "anyType"; }
object obj = new JavaScriptSerializer(new TypeResolver()).Deserialize<Options>(json);
"[{\"__type\":\"string\",\"Name\":\"DefaultSection\",\"Value\":\"SatelliteHolder\"},{\"__type\":\"string\",\"Name\":\"FillInterfaceName\",\"Value\":\"Bonus\"},{\"__type\":\"string\",\"Name\":\"FillFilterName\",\"Value\":\"SATELLITE FILL\"},{\"__type\":\"string\",\"Name\":\"FillSection:Position\",\"Value\":\"end\"},{\"__type\":\"string\",\"Name\":\"FillSection:Position\",\"Value\":\"end\"},{\"__type\":\"string\",\"Name\":\"FillSection:Position\",\"Value\":\"end\"},{\"__type\":\"string\",\"Name\":\"ConfigFillSectionType\",\"Value\":\"SpotsetHolder\"},{\"__type\":\"int\",\"Name\":\"MinAllowFillDistance\",\"Value\":240},{\"__type\":\"int\",\"Name\":\"MinGroupFillDistance\",\"Value\":10},{\"__type\":\"string\",\"Name\":\"SeparationFilterName\",\"Value\":\"SATELLITE SEPARATION\"},{\"__type\":\"string\",\"Name\":\"FillFilterSkip\",\"Value\":\"SATELLITE SKIP\"},{\"__type\":\"string\",\"Name\":\"ConfigSkipSectionType\",\"Value\":\"SpotsetHolder\"},{\"__type\":\"bool\",\"Name\":\"Performance\",\"Value\":false},{\"__type\":\"string\",\"Name\":\"VisibleSections\",\"Value\":\"HourHeader|SatelliteHolder\"}]"