MVC JsonNetResult - &#34; dataloss&#34;在序列化List <listitem> </listitem>时

时间:2014-05-31 19:18:28

标签: c# asp.net-mvc json serialization

我已经用ASP.NET MVC覆盖了默认的Json Serializer:

public class JsonNetResult : JsonResult
{
    public JsonNetResult()
    {
        Settings = new JsonSerializerSettings
                       {
                           ReferenceLoopHandling = ReferenceLoopHandling.Error,
                       };
    }

    public JsonSerializerSettings Settings { get; private set; }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");
        if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
            throw new InvalidOperationException("JSON GET is not allowed");

        HttpResponseBase response = context.HttpContext.Response;
        response.ContentType = string.IsNullOrEmpty(this.ContentType) ? "application/json" : this.ContentType;

        if (this.ContentEncoding != null)
            response.ContentEncoding = this.ContentEncoding;
        if (this.Data == null)
            return;

        var scriptSerializer = JsonSerializer.Create();

        using (var sw = new StringWriter())
        {
            scriptSerializer.Serialize(sw, this.Data);
            response.Write(sw.ToString());
        }
    }
}

当我序列化以下内容时:

public JsonResult GetLevels()
    {
        List<ListItem> items = new List<ListItem>();
        items.Add(new ListItem() { Text = "Home", Value = "5"});
        items.Add(new ListItem() { Text = "Live", Value = "6"});
        items.Add(new ListItem() { Text = "Dev", Value = "7"});
        items.Add(new ListItem() { Text = "Staging", Value = "8"});

        return Json(items, JsonRequestBehavior.AllowGet);
    }

我得到的JavaScript对象如下:

级别:数组[4] 0:&#34; Home&#34; 1:&#34;直播&#34; 2:&#34; Dev&#34; 3:&#34;分期&#34;

所以这里所有的信息都像价值一样丢失等等。 但是,当我使用Default Json序列化程序时,我得到了#34;右键&#34;序列化的信息

位: 阵列[4]

0:对象 属性:对象 启用:true 选中:假 文字:&#34; Home&#34; 价值:&#34; 5&#34;

1:对象 属性:对象 启用:true 选中:假 文字:&#34;直播&#34; 价值:&#34; 6&#34; ...

但由于DateTime序列化,我需要使用自定义序列化程序。 但我不知道自己在使用自定义JsonNetResult或我缺少的内容时遇到了什么问题。因为这里数据缺失或者

是不正常的

1 个答案:

答案 0 :(得分:2)

发生此问题是因为ListItem类已应用[TypeConverter]属性。当Json.Net看到这一点时,它使用相关的TypeConverter来获取值,而不是将其序列化为普通对象。在这种情况下,TypeConverter将ListItem转换为一个简单的字符串,这就是为什么你没有得到你期望的完整序列化。 JavaScriptSerializer(MVC使用的默认序列化程序)不进行此检查,因此在这种情况下ListItem会正常序列化。

您可以使用自定义ContractResolver告诉Json.Net将ListItem序列化为对象而不是使用TypeConverter。以下是您需要的代码:

class CustomContractResolver : DefaultContractResolver
{
    protected override JsonContract CreateContract(Type objectType)
    {
        if (objectType == typeof(ListItem))
            return base.CreateObjectContract(objectType);

        return base.CreateContract(objectType);
    }
}

将解析器添加到JsonSerializerSettings,您应该准备好了:

Settings = new JsonSerializerSettings
{
    ContractResolver = new CustomContractResolver(),
    ...        
};

注意:请确保在创建JsonSerializer时将设置传递给它 - 在您的代码中,您似乎没有这样做。

var scriptSerializer = JsonSerializer.Create(Settings);