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反序列化就做好了,是不是很简单,呵呵。



mvc使用mongodb时objectId序列化与反序列化,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。