2015-11-29 27 views
0

我正在使用CodeFluent JsonUtilities將對象轉換爲JSON。使用其他任何東西似乎都有其他各種問題(例如循環參考)。CodeFluent JSON序列化不適用於所有字段

下面是我使用CodeFluent.Runtime.Utilities命名空間(用於JsonUtilities)轉換爲JSON的ASP.NET MVC的一些函數。

public static ContentResult ConvertToJsonResponse(object obj) 
    { 
     string json = JsonUtilities.Serialize(obj); 
     return PrepareJson(json); 
    } 

    /// <summary> 
    /// Converts JSON string to a ContentResult object suitable as a response back to the client 
    /// </summary> 
    /// <param name="json"></param> 
    /// <returns></returns> 
    public static ContentResult PrepareJson(string json) 
    { 
     ContentResult content = new ContentResult(); 
     content.Content = json; 
     content.ContentType = "application/json"; 

     return content; 
    } 

問題是,當我使用JsonUtilities轉換似乎跳過了一些嵌套對象的對象。

例如,我試圖使用CodeFluent將DataSourceResult對象(從Telerik)轉換爲JSON。

public ActionResult UpdateTeam([DataSourceRequest]DataSourceRequest request, TeamViewModel teamViewModel) 
{ 
    ModelState.AddModelError("", "An Error!"); 
    DataSourceResult dataSourceResult = new[] { teamViewModel }.ToDataSourceResult(request, ModelState); 
    ContentResult ret = CodeFluentJson.ConvertToJsonResponse(dataSourceResult); 
    return ret; 
} 

的dataSourceResult擁有三個主要特性:

  1. 數據 - 它握住我的模型,包含我的數據。
  2. 總計 - 其中包含數據對象的數量。
  3. 錯誤 - 它包含我的MVC模型的所有錯誤。它非常嵌套,有很多屬性。

當我嘗試使用CodeFluent公用事業的DataSourceResult對象時,它的工作原理爲「數據」,以及「合計」字段轉換轉換,但有錯誤,它跳過它完全,導致下面的JSON字符串:

{ 
    "Data":[ 
     { 
     "ExampleProperty":"ExampleValue" 
     } 
    ], 
    "Total":1, 
    "AggregateResults":null, 
    "Errors":{ } 
} 

我猜測問題是CodeFluent轉換器的「錯誤」對象過於嵌套。 所以我的問題是有沒有任何CodeFluent序列化選項/代碼我失蹤與JSON轉換嚴重嵌套的對象工作?

+0

你能不能詳細說一下類是DataSourceResult?從什麼telerik產品? –

+0

看到這個鏈接: https://doylestowncoder.wordpress.com/2014/04/14/kendoui-understanding-todatasourceresult/ Telerik DataSourceResult對象來自Telerik ASP.NET MVC。它是一個默認類,用於將我的響應格式化爲發送給Telerk ASP.NET MVC Grid(以及可能使用DataSource對象的其他控件)。 對於我的MVC Grid上的讀取操作,它執行所有的分頁,排序,篩選和格式化我的模型對象和模型狀態錯誤,以便將其發送回MVC Grid以處理CRUD操作。 對於創建/更新/刪除,據我所知,它主要是用於錯誤處理的目的。 – Oniisaki

回答

1

問題出在您用空鍵創建模型錯誤的事實。它不被禁止,但JsonUtilities只是通過設計跳過一個空鍵的字典值。

只需使用一個真正的關鍵,是這樣的:

ModelState.AddModelError("my first error", "An Error!"); 
ModelState.AddModelError("my second error", "An Error!"); 

,你會看到錯誤收集系列化,像這樣:否則

{ 
"Data":[ 
    { 
    "ExampleProperty":"ExampleValue" 
    }], 
"Total": 1, 
"AggregateResults": null, 
"Errors": { 
    "my first error": { 
    "errors": [ 
     "An Error!" 
     ] 
    }, 
    "my second error": { 
    "errors": [ 
     "An Error!" 
     ] 
    } 
    } 
} 

,如果你真的想保持空鍵,那麼你可以利用帶有回調的JsonUtilitiesOptions類來調整序列化(和反序列化)過程。小心這個,因爲你可以很容易地打破JSON語法。這是你如何能做到這一點,在應該處理所有情況下的方式:

JsonUtilitiesOptions options = new JsonUtilitiesOptions(); 
options.WriteValueCallback += (e) => 
{ 
    IDictionary valueDic = e.Value as IDictionary; 
    if (valueDic != null) 
    { 
     e.Writer.Write('{'); 
     bool first = true; 
     foreach (DictionaryEntry entry in valueDic) 
     { 
      if (!first) 
      { 
       e.Writer.Write(','); 
      } 
      else 
      { 
       first = false; 
      } 

      // reuse JsonUtilities already written functions 
      JsonUtilities.WriteString(e.Writer, entry.Key.ToString(), e.Options); 
      e.Writer.Write(':'); 
      // object graph is for cyclic/infinite serialization checks 
      JsonUtilities.WriteValue(e.Writer, entry.Value, e.ObjectGraph, e.Options); 
     } 
     e.Writer.Write('}'); 
     e.Handled = true; // ok, we did it 
    } 
}; 
string json = JsonUtilities.Serialize(obj, options); 

現在,你會得到這樣的結果:

{ 
"Data":[ 
    { 
    "ExampleProperty":"ExampleValue" 
    }], 
"Total": 1, 
"AggregateResults": null, 
"Errors": { 
    "": { 
    "errors": [ 
     "An Error!" 
     ] 
    } 
    } 
} 
+0

這可以工作,但有沒有任何序列化程序選項,我可以將它設置爲不跳過帶空鍵的字典值?或者這個選項沒有提供? 不要放置存根鍵會很有用,因爲帶有此JSON對象的JavaScript使用「錯誤」中的這些鍵來指示哪些字段存在錯誤。在我的情況下,這是一個不是特定於字段的自定義錯誤。 – Oniisaki

+0

你可以用選項來做到這點(定義一個JsonUtilitiesOptions並在其上定義回調),但是它也需要一些額外的代碼。但是你是對的,空字符串在json中似乎是一個字典關鍵字(雖然有點奇怪)。我們將更改序列化程序,以便它不會跳過空(非空)字典鍵。請注意,與其他鍵一樣,給定字典中只能有一個空鍵。 –

+0

「你可以用選項來做到這一點(定義一個JsonUtilitiesOptions並定義回調)」。 我熟悉使用JsonUtilitiesOptions設置序列化選項,我如何定義它的回調以獲得我期待的效果? – Oniisaki