C# JSON反序列化对象

3

我是一名新手,对于C#并不是很了解。我想要反序列化JSON对象,但是遇到了一些问题。

以下是JSON对象:

var json  = "[{

  "idSite":"1",
  "visitorId":"a393fed00271f588",
  "actionDetails":[{
     "type":"action",
      "url":"http:\/\/mysite.info\/test-24\/",
      "customVariables":{
                  "1":{
                       "customVariablePageName1":"URL",
                       "customVariablePageValue1":"http:\/\/mysite.info\/p"
                       }
                   },
      "timeSpent":"78",
   }] 

}]";

我正在尝试以以下方式对其进行反序列化:

var visits = JsonConvert.DeserializeObject<VisitorDetails[]>(json);

public class VisitorDetails
{
    public string idSite { get; set; }

    public string visitorId { get; set; }

    public List<ActionDetail> actionDetails { get; set; }
}


public class ActionDetail
{
    public string type { get; set; }

    public string url { get; set; }

    public string timeSpent { get; set; }

    public object customVariables { get; set; }
}

除了“ActionDetails”中的“customVariables”只设置为一个字符串值的对象之外,一切都很好。
{
 "1":{
     "customVariablePageName1":"URL",
     "customVariablePageValue1":"http:\/\/mysite.info\/p"
     }
}

它根本没有反序列化。

我需要进行反序列化,这样我才能说:

foreach (var visit in Model.PiwikInfo)
{
   @foreach (var action in visit.actionDetails)
   {
      @if (action.customVariables != null && action.customVariables.Any())
      {
        foreach (var cv in visit.customVariables.Where(cv => cv.HasProperty("customVariablePageName1")))
        {
         <span>URL: @cv.GetProperty("customVariablePageValue1")</span>
        }
      }
   }
}
3个回答

5

这种情况发生是因为您指定了customVariables成员的类型为System.Object。因此,反序列化将导致将其赋予字符串值。

因此,我们尝试通过两个步骤将其塑造成更接近输入JSON结构和反序列化结果的特定使用形式,即更改customVariables成员变量的类型声明,并在每个更改后检查其反序列化内容。

  1. Make it a dictionary:

    public Dictionary<string, object> customVariables { get; set; }
    

    This will result in a dictionary that contains a single element with the key "1" and a single string value:

    {
        "customVariablePageName1": "URL",
        "customVariablePageValue1": "http://mysite.info/p"
    }
    
  2. Make it a dictionary of dictionaries:

    public Dictionary<string, Dictionary<string, string>> customVariables { get; set; }
    

    And print its deserialized ouput like this:

    var visits = JsonConvert.DeserializeObject<VisitorDetails[]>(json_string);
    
    foreach (var visit in visits)
    {
        Console.WriteLine("Visitor: {0}", visit.visitorId);
        foreach (var detail in visit.actionDetails)
        {
            Console.WriteLine("  Action: {0}", detail.type);
            foreach (var cv in detail.customVariables.Where(x => x.Value.ContainsKey("customVariablePageName1")))
            {
                Console.WriteLine("    Custom variable #{0}", cv.Key);
                Console.WriteLine("    Value: {0}", cv.Value["customVariablePageValue1"]);
            }
        }
    }
    

    Which resembles your view's foreach, and will produce the following output:

    Visitor: a393fed00271f588
      Action: action
        Custom variable #1
        Value: http://mysite.info/p
    

0

因为我还不能评论,所以我必须把这个发帖作为答案。你试过使用 C# 的内置函数吗?请看这里

另外,根据我的了解,在该方法的文档中,它将 JSON 转换为系统对象。

此外,从外观上看,customVariables 段可能是一个数组或一个损坏的对象。我这么说是因为它缺少前几个声明中的方括号,看起来像这样:

...
"customVariables":[{
                  "1":[{
                       "customVariablePageName1":"URL",
                       "customVariablePageValue1":"http:\/\/mysite.info\/p"
                       }]
                   }],
...

希望能有所帮助。


1
我无法更改JSON,因为我从一个API的响应中获取它。而且也没有尝试使用内置函数,因为出于某种原因,我需要按照这种方式工作。 - carpics

0

尝试使用这个结构

    public class T1
{
    public string customVariablePageName1 { get; set; }
    public string customVariablePageValue1 { get; set; }
}

public class CustomVariables
{
    public T1 t1 { get; set; }
}

public class ActionDetail
{
    public string type { get; set; }
    public string url { get; set; }
    public CustomVariables customVariables { get; set; }
    public string timeSpent { get; set; }
}

public class RootObject
{
    public string idSite { get; set; }
    public string visitorId { get; set; }
    public List<ActionDetail> actionDetails { get; set; }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接