ServiceStack.Text中的数组反序列化不正确

时间:2013-03-23 19:43:46

标签: c# json servicestack

我有这个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"}}

我正在使用此对象进行反序列化: -

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);
  }
}

SearchResponse本身被解释得很好(耶!)但搜索结果子对象不正确 - 它看起来就像顶级SearchResponse。

这是以下日志行给我的内容: -

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());
  }

此日志输出: -

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

任何人都知道如何修复它?

提前致谢。

1 个答案:

答案 0 :(得分:4)

如果您选择动态解析JSON,则从JsonObject检索的值默认是转义标量值。如果要解析数组,则需要使用T.ArrayObjects()扩展方法,例如:

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

如果要从 JsonObject 获取原始未转义值,则需要通过GetUnescaped()方法检索它,例如:

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

typedResults.PrintDump();

输出:

[
    {
        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>"
    }
]