Incorrect array deserialization in ServiceStack.Text

I have this JSON: -

{"snippet-format":"raw","total":1,"start":1,"page-length":200,"results":[{"index":1,"uri":"/myproject/info.xml","path":"fn:doc(\"/myproject/info.xml\")","score":0,"confidence":0,"fitness":0,"content":"<root xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"\" xmlns:search=\"http://marklogic.com/appservices/search\"><content>Adams Project file</content></root>"}],"facets":{"lastmodified":{"type":"xs:dateTime","facetValues":[]}},"metrics":{"query-resolution-time":"PT0.002559S","facet-resolution-time":"PT0.00111S","snippet-resolution-time":"PT0.000043S","total-time":"PT0.0039S"}} 

What I am deserializing with this object: -

 public class SearchResponse : MarkLogicObject { // response fields public string SnippetFormat {get;set;} public int Total {get;set;} public int Start {get;set;} public int PageLength {get;set;} public SearchResult[] Results { get; set; } public string Warning {get;set;} public override string ToString () { return "SnippetFormat: " + SnippetFormat + ", Total: " + Total + ", Start: " + Start + ", Warning: " + Warning; } public static SearchResponse ParseJson(string json) { var map = JsonObject.Parse(json); return new SearchResponse { Total = int.Parse (map["total"]), Start = int.Parse (map["start"]), PageLength = int.Parse (map ["page-length"]), SnippetFormat = map ["snippet-format"], Warning = map["warning"], Results = map["results"].FromJson<SearchResult[]>() // why doesn't this deserialise properly? It creates a SearchResponse object mirroring this one instead. }; } } // Sub elements of SearchResponse public class SearchResult { public string Uri {get;set;} public long Index { get; set; } public string Path {get;set;} public double Score {get;set;} public double Fitness {get;set;} public double Confidence {get;set;} public string Content { get; set; } // JSON or XML content (probably XML, no matter what ?format=json says) public override string ToString () { return string.Format ("[SearchResult: Uri={0}, Index={1}, Path={2}, Score={3}, Fitness={4}, Confidence={5}, Content={6}]", Uri, Index, Path, Score, Fitness, Confidence, Content); } } 

The SearchResponse query itself is interpreted perfectly (yay!), But the Result Result child object is incorrect - it looks the same as the top-level SearchResponse.

Here is what the following log lines give me: -

 HttpWebResponse webResponse = restClient.Get<HttpWebResponse>(completePath("/v1/search",qp)); using (var stream = webResponse.GetResponseStream()) using (var sr = new StreamReader(stream)) { var text = sr.ReadToEnd(); log.log ("response text: " + text); result = text.FromJson<SearchResponse>(); } log.log ("RESULT: " + result.ToString ()); for (int i = 0; i < result.Results.Length; i++) { log.log ("Result " + i + ": " + result.Results[i].ToString()); } 

This log output is: -

 19:30:24 | SparkleMLLogger | RESULT: SnippetFormat: raw, Total: 1, Start: 1, Warning: 19:30:24 | SparkleMLLogger | Result: SnippetFormat: raw, Total: 1, Start: 1, Warning: 

Does anyone have an idea how to fix it?

Thanks in advance.

+4
source share
1 answer

If you want to dynamically parse JSON, the values ​​that are extracted from JsonObject default to escaped values. If you want to T.ArrayObjects() array, you need to use the T.ArrayObjects() extension method, for example:

 JsonArrayObjects results = JsonObject.Parse(json).ArrayObjects("results"); string url = results[0]["uri"]; url.Print(); // /myproject/info.xml 

If you want to get the raw raw value from JsonObject , you need to get it using the GetUnescaped() method, for example:

 SearchResult[] typedResults = JsonObject.Parse(json) .GetUnescaped("results") .FromJson<SearchResult[]>(); typedResults.PrintDump(); 

Output:

 [ { Uri: /myproject/info.xml, Index: 1, Path: "fn:doc(""/myproject/info.xml"")", Score: 0, Fitness: 0, Confidence: 0, Content: "<root xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns="""" xmlns:search=""http://marklogic.com/appservices/search""><content>Adams Project file</content></root>" } ] 
+3
source

All Articles