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<string,taskParam> resDict = new Dictionary<string,taskParam>();
resDict.Add("output_Buffer",new taskParam(){ paramUrl = "results/output_Buffer"});
resDict.Add("Final_wellpoints",new taskParam(){ paramUrl = "results/Final_wellpoints"});
Dictionary<string,taskParam> inputDict = new Dictionary<string,taskParam>();
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<message>()
{
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<string, taskParam> results { get; set; }
[DataMember(Order = 3)]
public Dictionary<string, taskParam> inputs { get; set; }
[DataMember(Order = 4)]
public List<message> 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).