我正在使用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
它可以正常工作,但这很乏味且耗时且容易出错。我不想将其添加到每个模型中。我希望始终DateTimeModelBinder
和DateTime
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"));
它有效!
答案 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,请检查您是否混淆了这些类型 - 许多类型具有相同或相似的名称,只是它们位于不同的名称空间中。