MVC JsonNetResult-"dataloss"在序列化List< ListItem>时 [英] MVC JsonNetResult - "dataloss" when serializing List<ListItem>

查看:55
本文介绍了MVC JsonNetResult-"dataloss"在序列化List< ListItem>时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已使用以下命令覆盖了ASP.NET MVC中的默认Json序列化器:

I've overwritten the default Json Serializer from ASP.NET MVC with:

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());
        }
    }
}

当我序列化以下内容时:

And when I am Serializing the Following:

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对象如下:

The JavaScript Object I get is the following:

级别:数组[4]0:首页"1:直播"2:开发"3:分期"

Levels: Array[4] 0: "Home" 1: "Live" 2: "Dev" 3: "Staging"

因此,在这里我所有的信息都像价值一样丢失,依此类推.但是,当我使用Default Json序列化程序时,我得到了正确的"信息序列化

So here all my Informations are lost like value and so on. But when I use the Default Json serializer then I got the "right" Informations serialized

级别:数组[4]

0:对象属性:对象已启用:true选择:错误文字:首页"值:"5"

0: Object Attributes: Object Enabled: true Selected: false Text: "Home" Value: "5"

1:对象属性:对象已启用:true选择:错误文字:直播"值:"6"...

1: Object Attributes: Object Enabled: true Selected: false Text: "Live" Value: "6" ...

但是由于DateTime序列化,我需要使用自定义序列化器.但是我不知道自定义JsonNetResult在做什么或我缺少什么.因为这是数据丢失还是不正常?

but I need to use the custom serializer because of the DateTime serialization. But I don't know what I am doing wrong with the custom JsonNetResult or what I am missing. Because it can't be normal that here is Data missing or?

推荐答案

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

This problem happens because the ListItem class has a [TypeConverter] attribute applied to it. When Json.Net sees this, it uses the associated TypeConverter to get the value instead of serializing it as a normal object. In this case the TypeConverter converts the ListItem to a simple string, so that is why you do not get the full serialization you are expecting. The JavaScriptSerializer (the default serializer used by MVC) does not do this check, so the ListItem serializes normally in that case.

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

You can use a custom ContractResolver to tell Json.Net to serialize ListItem as an object instead of using a TypeConverter. Here is the code you would need:

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

        return base.CreateContract(objectType);
    }
}

将解析器添加到您的 JsonSerializerSettings 中,就可以开始了:

Add the resolver to your JsonSerializerSettings and you should be ready to go:

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

注意:请确保在创建 JsonSerializer 时将设置传递给它-在代码中看起来好像您没有这样做.

Note: be sure that when you create the JsonSerializer that you pass the settings to it-- in your code it looks like you are not doing this.

var scriptSerializer = JsonSerializer.Create(Settings);

这篇关于MVC JsonNetResult-"dataloss"在序列化List&lt; ListItem&gt;时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆