mvc中默认使用的json返回序列化工具是JsonValueProviderFactory,JsonValueProviderFactory继承自ValueProviderFactory抽象类。JsonValueProviderFactory使用的序列化类库是System.Web.Script.Serialization。现在我们来写一个自己的方序列话工具,采用的是Newtonsoft.Json序列化和反序列化工具。
JsonValueProviderFactory代码具体如下:
using System; using System.Collections; using System.Collections.Generic; using System.Dynamic; using System.Globalization; using System.IO; using System.Web.Mvc; using Newtonsoft.Json; using Newtonsoft.Json.Converters; namespace Aft.Build.MvcWeb.Common { public class JsonNetValueProviderFactory : ValueProviderFactory { public override IValueProvider GetValueProvider(ControllerContext controllerContext) { // first make sure we have a valid context if (controllerContext == null) throw new ArgumentNullException("controllerContext"); // now make sure we are dealing with a json request if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase)) return null; // get a generic stream reader (get reader for the http stream) var streamReader = new StreamReader(controllerContext.HttpContext.Request.InputStream); // convert stream reader to a JSON Text Reader var jsonReader = new JsonTextReader(streamReader); // tell JSON to read if (!jsonReader.Read()) return null; // make a new Json serializer var jsonSerializer = new JsonSerializer(); // add the dyamic object converter to our serializer jsonSerializer.Converters.Add(new ExpandoObjectConverter()); // use JSON.NET to deserialize object to a dynamic (expando) object Object jsonObject; // if we start with a "[", treat this as an array if (jsonReader.TokenType == JsonToken.StartArray) jsonObject = jsonSerializer.Deserialize<List<ExpandoObject>>(jsonReader); else jsonObject = jsonSerializer.Deserialize<ExpandoObject>(jsonReader); // create a backing store to hold all properties for this deserialization var backingStore = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase); // add all properties to this backing store AddToBackingStore(backingStore, String.Empty, jsonObject); // return the object in a dictionary value provider so the MVC understands it return new DictionaryValueProvider<object>(backingStore, CultureInfo.CurrentCulture); } private static void AddToBackingStore(Dictionary<string, object> backingStore, string prefix, object value) { var d = value as IDictionary<string, object>; if (d != null) { foreach (var entry in d) { AddToBackingStore(backingStore, MakePropertyKey(prefix, entry.Key), entry.Value); } return; } var l = value as IList; if (l != null) { for (int i = 0; i < l.Count; i++) { AddToBackingStore(backingStore, MakeArrayKey(prefix, i), l[i]); } return; } // primitive backingStore[prefix] = value; } private static string MakeArrayKey(string prefix, int index) { return prefix + "[" + index.ToString(CultureInfo.InvariantCulture) + "]"; } private static string MakePropertyKey(string prefix, string propertyName) { return (String.IsNullOrEmpty(prefix)) ? propertyName : prefix + "." + propertyName; } } }
然后把JsonValueProviderFactory注册给全局json数据反序列化使用:
在Global.asax文件Application_Start方法中添加如下两行代码:
ValueProviderFactories.Factories.Remove(ValueProviderFactories.Factories.OfType<JsonValueProviderFactory>().FirstOrDefault()); ValueProviderFactories.Factories.Add(new JsonNetValueProviderFactory());
第一句是移除原来的JsonValueProviderFactory反序列化,第二句是添加自己的反序列化工具。
总结及注意事项:
1.mvc客户端数据到服务器段的数据类型转换都是在通过ValueProviderFactories来注册的。
2.切记mvc中通过ajax来传到服务器段的数据报文头记得一定要Content-Type:application/json,不然不会使用我们上面自己的JsonNetValueProviderFactory反序列化工具
mvc使用Newtonsoft.Json反序列化json数据
时间: 2024-10-12 23:54:08