CodeFluent JSON序列化不适用于所有字段

时间:2015-11-29 06:03:57

标签: json model-view-controller telerik codefluent

我正在使用CodeFluent JsonUtilities将对象转换为JSON。使用其他任何东西似乎都有其他各种问题(例如循环引用)。

这里有一些我用来转换为ASP.NET MVC的JSON的函数,使用CodeFluent.Runtime.Utilities命名空间(对于JsonUtilities)。

    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模型的所有错误。它非常嵌套,下面有很多属性。
  4. 当我尝试使用CodeFluent实用程序转换DataSourceResult对象时,它可以转换“数据”和“总计”字段,但是有了错误,它会完全跳过它,导致下面的JSON字符串:

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

    我猜测问题是“错误”对象过于嵌套了CodeFluent转换器。 所以我的问题是,是否有任何CodeFluent序列化选项/代码我缺少使用大量嵌套对象进行JSON转换?

1 个答案:

答案 0 :(得分: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!"
      ]
    }
  }
}