我已经用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或我缺少的内容时遇到了什么问题。因为这里数据缺失或者
是不正常的答案 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);