How do I serialize/deserialize .NET dictionary without key value elements?

المشرف العام

Administrator
طاقم الإدارة
I'm trying to get my C# class to serialize to a json that complies with GP Job, for example:

{ "jobId" : "jb10b153b77e74a839e31af53e5d4d0d1", "jobStatus" : "esriJobSucceeded", "results" : { "output_Buffer" : {"paramUrl" : "results/output_Buffer"}, "Final_wellpoints" : {"paramUrl" : "results/Final_wellpoints"} }, "inputs" : { "Input_Features" : {"paramUrl" : "inputs/Input_Features"}, "Distance" : {"paramUrl" : "inputs/Distance"} }, "messages" : [ {"type" : "esriJobMessageTypeInformative", "description" : "Submitted."}, {"type" : "esriJobMessageTypeInformative", "description" : "Executing..."}, {"type" : "esriJobMessageTypeInformative", "description" : "Succeeded."} ] } But my dictionaries (results and inputs) serialize with key/value cruft:

// { "jobId":"jb10b153b77e74a839e31af53e5d4d0d1", "jobStatus":"esriJobSucceeded", "results":[ {"Key":"output_Buffer", "Value": {"paramUrl":"results/output_Buffer"}}, {"Key":"Final_wellpoints", "Value": {"paramUrl":"results/Final_wellpoints"}}], "inputs":[ {"Key":"Input_Features", "Value": {"paramUrl":"inputs/Input_Features"}}, {"Key":"Distance", "Value": {"paramUrl":"inputs/Distance"}}], "messages":[ {"type":"esriJobMessageTypeInformative", "description":"Submitted."}, {"type":"esriJobMessageTypeInformative", "description":"Executing..."}, {"type":"esriJobMessageTypeInformative", "description":"Succeeded."} ] } Update: I've commented out the WCF code and replaced with Json.NET call.

[DataContract] public class GPJob { public static string Test() { Dictionary resDict = new Dictionary(); resDict.Add("output_Buffer",new taskParam(){ paramUrl = "results/output_Buffer"}); resDict.Add("Final_wellpoints",new taskParam(){ paramUrl = "results/Final_wellpoints"}); Dictionary inputDict = new Dictionary(); inputDict.Add("Input_Features", new taskParam(){paramUrl="inputs/Input_Features"}); inputDict.Add("Distance", new taskParam(){paramUrl="inputs/Distance"}); GPJob job = new GPJob { jobId = "jb10b153b77e74a839e31af53e5d4d0d1", jobStatus = "esriJobSucceeded", results = resDict, inputs = inputDict, messages = new List() { new message(){type="esriJobMessageTypeInformative",description = "Submitted."}, new message(){type="esriJobMessageTypeInformative",description = "Executing..."}, new message(){type="esriJobMessageTypeInformative",description = "Succeeded."} } }; string json = JsonConvert.SerializeObject(job,Formatting.Indented); return json; /* DataContractJsonSerializer ser = new DataContractJsonSerializer(job.GetType()); System.IO.MemoryStream ms = new System.IO.MemoryStream(); ser.WriteObject(ms, job); string json = Encoding.Default.GetString(ms.ToArray()); return json; */ } [DataMember(Order=0)] public string jobId { get; set; } [DataMember(Order = 1)] public string jobStatus { get; set; } [DataMember(Order = 2)] public Dictionary results { get; set; } [DataMember(Order = 3)] public Dictionary inputs { get; set; } [DataMember(Order = 4)] public List messages { get; set; } } [DataContract] public class taskParam { [DataMember] public string paramUrl { get; set; } } [DataContract] public class message { [DataMember(Order=0)] public string type { get; set; } [DataMember(Order = 1)] public string description { get; set; } } Here's the output:

{ "jobId": "jb10b153b77e74a839e31af53e5d4d0d1", "jobStatus": "esriJobSucceeded", "results": { "output_Buffer": { "paramUrl": "results/output_Buffer" }, "Final_wellpoints": { "paramUrl": "results/Final_wellpoints" } }, "inputs": { "Input_Features": { "paramUrl": "inputs/Input_Features" }, "Distance": { "paramUrl": "inputs/Distance" } }, "messages": [ { "type": "esriJobMessageTypeInformative", "description": "Submitted." }, { "type": "esriJobMessageTypeInformative", "description": "Executing..." }, { "type": "esriJobMessageTypeInformative", "description": "Succeeded." } ] } Update2 Looks like I spoke too soon, deserialization of this string fails:

string json = "{\"jobId\":\"jeabfba358b69412abeafd63e415957bf\",\"jobStatus\":\"esriJobWaiting\"," + "\"results\":[],\"inputs\":[],\"messages\":[]}"; GPJob j= JsonConvert.DeserializeObject(json, typeof(GPJob),JsonSerializerSettings) as GPJob; I get this exception:

Cannot deserialize JSON array into type 'System.Collections.Generic.Dictionary`2[System.String,Anadarko.iMaps.JobLib.taskParam]' It works ok when the results and inputs are not empty.

Update3:

This string deserializes:

{"jobId":"jeabfba358b69412abeafd63e415957bf","jobStatus":"esriJobWaiting","results":null,"inputs":null,"messages":null} So here's the hack:

// hack: replace [] with null string hackedJson = json.Replace("[]", "null"); GPJob j= JsonConvert.DeserializeObject(hackedJson, typeof(GPJob)) as GPJob; Of course this results in a null instead of an empty dictionary. Any idea where that might cause an issue (if so, I guess I could handle that in the setters).



أكثر...
 
أعلى