mvc使用mongodb时objectId序列化与反序列化

前面有写使用自己的mvc 序列化工具即jsonNetResult。我这里结合之前写的jsonNetResult来做一个Json序列化工具,而且序列化ObjectId成一个字符串。详细代码例如以下

using System;
using System.IO;
using System.Text;
using System.Web.Mvc;
using Aft.Build.Common;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace Aft.Build.MvcWeb.Common
{
    public class JsonNetResult : JsonResult
    {
        public JsonNetResult()
        {
            Settings = new JsonSerializerSettings
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Error
            };
        }
        public JsonNetResult(object data, JsonRequestBehavior behavior = JsonRequestBehavior.AllowGet, string contentType = null, Encoding contentEncoding = null)
        {
            Data = data;
            JsonRequestBehavior = behavior;
            ContentEncoding = contentEncoding;
            ContentType = contentType;
        }

        private JsonSerializerSettings _settings;
        public JsonSerializerSettings Settings
        {
            get
            {
                _settings = _settings ?? new JsonSerializerSettings();
                _settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                _settings.Converters.Add(new ObjectIdConverter());
                return _settings;
            }
            private set { _settings = value; }
        }

        public override void ExecuteResult(ControllerContext context)
        {

            if (context == null)
                throw new ArgumentNullException("context");
            if (JsonRequestBehavior == JsonRequestBehavior.DenyGet && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
                throw new InvalidOperationException("JSON GET is not allowed");
            var response = context.HttpContext.Response;
            response.ContentType = string.IsNullOrEmpty(ContentType) ? "application/json" : ContentType;

            if (ContentEncoding != null)
                response.ContentEncoding = ContentEncoding;
            if (Data == null)
                return;
            var scriptSerializer = JsonSerializer.Create(Settings);
            using (var sw = new StringWriter())
            {
                scriptSerializer.Serialize(sw, Data);
                response.Write(sw.ToString());
            }
        }
    }
}


在jsonnetresult加入一行如图所看到的代码:

_settings.Converters.Add(new ObjectIdConverter());

我们的ObjectIdConverter详细实现例如以下:

using System;
using MongoDB.Bson;
using Newtonsoft.Json;

namespace Aft.Build.Common
{
    public class ObjectIdConverter : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            serializer.Serialize(writer, value.ToString());
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            ObjectId result;
            ObjectId.TryParse(reader.Value as string, out result);
            return result;
        }

        public override bool CanConvert(Type objectType)
        {
            return typeof(ObjectId).IsAssignableFrom(objectType);
        }
    }
}
这样JsonNetResult就具备能够序列化ObjectId类型的数据了。

当然其它有特殊须要序列的话的东西实现方式类同。

序列化完毕了。接下来是反序列化。假设不经处理Objectid字符串是没有办法反序列ObjectId对象的会变成Objectid.empt(即全是零0),或者是使用字符串来接收,可是这不是我们希望看到的。

我们使用mvc ModelBinder 来实现ObjectId对象的反序列化

详细代码例如以下:

加入引用

using System;
using System.Web.Mvc;
using MongoDB.Bson;

代码实现:

public class ObjectIdModelBinder : IModelBinder
    {

        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelType != typeof(ObjectId))
            {
                return ObjectId.Empty;
            }
            var val = bindingContext.ValueProvider.GetValue(
                bindingContext.ModelName);
            if (val == null)
            {
                return ObjectId.Empty;
            }

            var value = val.AttemptedValue;
            if (value == null)
            {
                bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Wrong value type");
                return ObjectId.Empty;
            }
            ObjectId result;
            if (ObjectId.TryParse(value, out result))
            {
                return result;
            }
            return ObjectId.Empty;
        }
    }
    public class ObjectIdProvider : IModelBinderProvider
    {
        public IModelBinder GetBinder(Type modelType)
        {
            if (modelType == typeof(ObjectId) || modelType == typeof(ObjectId?))
            {
                return new ObjectIdModelBinder();
            }
            return null;
        }
    }


全局注冊,在Global.asax文件Application_Start方法中加入例如以下代码:

ModelBinderProviders.BinderProviders.Add(new ObjectIdProvider());
这样ObjectId反序列化就做好了,是不是非常easy,呵呵。



原文地址:https://www.cnblogs.com/cxchanpin/p/6898032.html