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"}}
Which I'm deserialising using 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 itself is interpreted fine (yay!) but the Search Result child object is incorrect - it looks just like the top level SearchResponse.
Here's 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:-
19:30:24 | SparkleMLLogger | RESULT: SnippetFormat: raw, Total: 1, Start: 1, Warning:
19:30:24 | SparkleMLLogger | Result: SnippetFormat: raw, Total: 1, Start: 1, Warning:
Anyone have an idea how to fix it?
Thanks in advance.
If you're choosing to dynamically parse JSON, the values that are retrieved from the JsonObject are by default escaped scalar values. If you want to parse an array you need to use the T.ArrayObjects()
extension method, e.g:
JsonArrayObjects results = JsonObject.Parse(json).ArrayObjects("results");
string url = results[0]["uri"];
url.Print(); // /myproject/info.xml
If you want to get the raw un-escaped value from the JsonObject you need retrieve it via the GetUnescaped()
method, e.g:
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>"
}
]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With