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

CodeFluent JSON Serialization Does Not Work for All Fields

我正在使用 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. Errors - 它包含我的 MVC 模型的所有错误。非常嵌套,下面有很多属性

当我尝试使用 CodeFluent 实用程序转换 DataSourceResult 对象时,它可以转换 "Data" 和 "Total" 字段,但由于错误,它会完全跳过它,从而导致下面的 JSON 字符串:

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

我猜问题出在 "Errors" 对象对于 CodeFluent 转换器而言过于嵌套。 所以我的问题是是否有任何 CodeFluent 序列化 options/code 我缺少使用大量嵌套对象进行 JSON 转换?

问题出在您使用空键创建模型错误。这不是禁止的,但 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 class 来调整序列化(和反序列化)过程。小心这一点,因为您很容易破坏 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!"
      ]
    }
  }
}