2015-05-20 191 views
3

我是C#的新手,所以我不太瞭解它。我想反序列化json對象,但我遇到了一些問題。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; } 
} 

一切都很好,除了在 「customVariables」 「ActionDetails」 它只是設置以一個值作爲字符串反對:

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

回答

5

嗯,發生這種情況是因爲您已指定customVariables成員的類型爲System.Object。因此,反序列化會導致爲其分配字符串值。

因此,讓我們嘗試通過更改customVariables成員變量的類型聲明並在檢查其反序列化的內容之後,通過兩個步驟將它塑造成更類似於輸入JSON結構和您對特定反序列化結果的使用的形狀每個變化。

  1. 使它成爲一個字典

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

    這將導致包含關鍵"1"和一個字符串值的單個元素的字典:

    { 
        "customVariablePageName1": "URL", 
        "customVariablePageValue1": "http://mysite.info/p" 
    } 
    
  2. 做一個詞典的翻譯:

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

    並打印其反序列化輸出中是這樣的:

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

    它類似於您的視圖的foreach,並會產生以下的輸出:

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

既然我無法評論還是我將不得不張貼此作爲一個答案。你有沒有嘗試過使用C#的內置函數? See Here

另外,從我收集的文檔中可以看出,它轉換成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; } 
}