简体   繁体   English

自定义DateTime模型联编程序不起作用

[英]custom DateTime model binder not working

I am using Asp.Net MVC 4 and this is my custom model binder: 我正在使用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;
        }
    }

and this is my Web API method: 这是我的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 has BirthDate of type DateTime? registrationUser是否具有DateTime?类型的BirthDate DateTime? . When I submit a valid value 23/05/2014 it won't accept and model binder is never executed. 当我提交有效值23/05/2014 ,它将不接受,并且永远不会执行模型联编程序。

I have this in global.asax: 我在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();

        }

This is my RegistrationUser POCO: 这是我的注册用户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; }
    }

What am I missing? 我想念什么?

PS: If I add an attribute PS:如果我添加属性

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

it would work fine but this is tedious and time consuming plus error prone. 它可以正常工作,但是这很繁琐且耗时,而且容易出错。 I don't want to add this to each model. 我不想将此添加到每个模型。 I want that DateTimeModelBinder should be used always for DateTime and DateTime? 我希望DateTimeModelBinder应该始终用于DateTimeDateTime?

Update: 更新:

Looks like I needed to use JSON.Net's converter feature: 看起来我需要使用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));
        }
    }

and then I had to add this in WebApiConfig: 然后我必须在WebApiConfig中添加它:

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

and it works! 而且有效!

It looks like you are writing an MVC model binder and trying to use it in a Web API controller. 您似乎正在编写MVC模型绑定程序,并试图在Web API控制器中使用它。 The two systems are similar, but not compatible with each other in terms of the types being used. 两种系统是相似的,但在使用的类型方面彼此不兼容。

The types in the System.Web.Mvc namespace are all MVC, whereas the types in the System.Web.Http namespaces are all Web API. System.Web.Mvc命名空间中的类型都是MVC,而System.Web.Http命名空间中的类型都是Web API。

The registration of MVC and Web API model binders is also similar in some ways, and different in others. MVC和Web API模型绑定程序的注册在某些方面也相似,而在其他方面则不同。 For example, you can use the [ModelBinder(typeof(XyzModelBinder))] attribute on the type in question to declare a model binder in both systems. 例如,可以在所讨论的类型上使用[ModelBinder(typeof(XyzModelBinder))]属性在两个系统中声明模型绑定程序。 But registration of a global model binder is different. 但是,全局模型联编程序的注册是不同的。

In MVC you register a global model binder like so: 在MVC中,您可以像这样注册全局模型联编程序:

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

In Web API it is like so: 在Web API中,就像这样:

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

With regard to MVC vs. Web API, please check that you're not mixing up those types - many types have the same or similar name except that they're in different namespaces. 关于MVC与Web API,请检查您是否没有混淆这些类型-许多类型具有相同或相似的名称,只是它们位于不同的命名空间中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM