自定义DateTime模型绑定器不起作用

时间:2014-05-24 05:39:39

标签: c# asp.net asp.net-mvc asp.net-mvc-4 datetime

我正在使用Asp.Net MVC 4,这是我的自定义模型绑定器:

public class DateTimeModelBinder : DefaultModelBinder
    {
        private string _customFormat;

        public DateTimeModelBinder(string customFormat)
        {
            _customFormat = customFormat;
        }

        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            if(value != null)
                return DateTime.ParseExact(value.AttemptedValue, _customFormat, CultureInfo.InvariantCulture);
            return null;
        }
    }

这是我的Web API方法:

[HttpPost]
        public HttpResponseMessage Register(RegistrationUser registrationUser)
        {
            if (ModelState.IsValid)
            {

                return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("User is created") };
            }
            else
            {
                return new HttpResponseMessage(HttpStatusCode.BadRequest)
                {
                    Content =
                        new ObjectContent<IEnumerable<string>>(ModelState.Values.SelectMany(f => f.Errors.Select(s => s.ErrorMessage)),
                        new JsonMediaTypeFormatter())
                };
            }
        }

registrationUser的BirthDate类型为DateTime?。当我提交有效值23/05/2014时,它不会接受,并且模型活页夹永远不会被执行。

我在global.asax中有这个:

protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            ModelBinders.Binders.Add(typeof(DateTime), new DateTimeModelBinder("dd/mm/yyyy"));
            ModelBinders.Binders.Add(typeof(DateTime?), new DateTimeModelBinder("dd/mm/yyyy"));

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            AuthConfig.RegisterAuth();

        }

这是我的RegistrationUser POCO:

 public class RegistrationUser
    {
        public int UserID { get; set; }

        [Required(ErrorMessage = "Email address is required")]
        [EmailAddress(ErrorMessage = "Invalid Email Address")]
        public string EmailAddress { get; set; }

        [Required(ErrorMessage = "First Name is required")]
        public string FirstName { get; set; }

        [Required(ErrorMessage = "Last Name is required")]
        public string LastName { get; set; }

        [Required(ErrorMessage = "Password is required")]
        public string Password { get; set; }

        [NullableRequired(ErrorMessage = "Gender is required")]
        public short? GenderID { get; set; }

        [NullableRequired(ErrorMessage = "Birth Date is required")]
        public DateTime? BirthDate { get; set; }

        [NullableRequired(ErrorMessage = "Profile For is required")]
        public short? ProfileForID { get; set; }
    }

我错过了什么?

PS:如果我添加属性

[ModelBinder(typeof(DateTimeModelBinder))]
    public class RegistrationUser

它可以正常工作,但这很乏味且耗时且容易出错。我不想将其添加到每个模型中。我希望始终DateTimeModelBinderDateTime

使用DateTime?

更新

看起来我需要使用JSON.Net的转换器功能:

public class DateTimeConverter : DateTimeConverterBase
    {
         private string _dateFormat;

         public DateTimeConverter(string dateFormat)
        {
            _dateFormat = dateFormat;
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            try
            {
                if (reader.Value != null && reader.Value.ToString().Trim() != string.Empty)
                    return DateTime.ParseExact(reader.Value.ToString(), _dateFormat, CultureInfo.InvariantCulture);
            }
            catch
            {                
            }
            return null;
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            writer.WriteValue(((DateTime)value).ToString(_dateFormat));
        }
    }

然后我不得不在WebApiConfig中添加它:

config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(
             new DateTimeConverter("dd/mm/yyyy"));

它有效!

1 个答案:

答案 0 :(得分:3)

看起来您正在编写MVC模型绑定器并尝试在Web API控制器中使用它。这两个系统相似,但在使用的类型方面彼此不兼容。

System.Web.Mvc命名空间中的类型都是MVC,而System.Web.Http命名空间中的类型都是Web API。

MVC和Web API模型绑定器的注册在某些方面也类似,在其他方面也不同。例如,您可以使用相关类型的[ModelBinder(typeof(XyzModelBinder))]属性在两个系统中声明模型绑定器。但是全球模型活页夹的注册是不同的。

在MVC中,您可以注册一个全局模型绑定器,如下所示:

ModelBinders.Binders.Add(typeof(Xyz), new XyzModelBinder(...));

在Web API中就是这样:

GlobalConfiguration.Configuration.Services.Add(typeof(ModelBinderProvider), new XyzModelBinderProvider());

关于MVC与Web API,请检查您是否混淆了这些类型 - 许多类型具有相同或相似的名称,只是它们位于不同的名称空间中。