类型可为空时,不调用自定义模型绑定器

Ren*_*ené 7 c# custom-model-binder asp.net-mvc-3

我有一个自定义结构TimeOfDay,在这样的视图模型中使用它:

public class MyViewModel
{
  public TimeOfDay TimeOfDay { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我创建了一个自定义模型绑定器TimeOfDayModelBinder,并在Global.asax.cs中注册它,如下所示:

ModelBinders.Binders.Add(typeof(TimeOfDay), new TimeOfDayModelBinder());
Run Code Online (Sandbox Code Playgroud)

一切都很好.但是,如果我将我的视图模型更改为:

public class MyViewModel
{
  public TimeOfDay? TimeOfDay { get; set; } // Now nullable!
}
Run Code Online (Sandbox Code Playgroud)

我的自定义模型绑定器不再被调用.我知道该属性不再是TimeOfDay的类型,而是一个不同的Nullable.这是否意味着我应该在Global.asax.cs中添加我的自定义模型绑定器两次,如下所示:

ModelBinders.Binders.Add(typeof(TimeOfDay), new TimeOfDayModelBinder());
ModelBinders.Binders.Add(typeof(TimeOfDay?), new TimeOfDayModelBinder());
Run Code Online (Sandbox Code Playgroud)

它有效,但有一些我不喜欢的东西.这是否真的有必要将我的类型处理为可空,或者是否有我缺少的东西?

Lin*_*ron 8

这不是你问题的真正答案,而是另一种解决方案.可能会有更好的......

在MVC3中,您可以创建IModelBinderProvider.实现将是这样的:

public class TimeOfDayModelBinderProvider : IModelBinderProvider
{
    public IModelBinder GetBinder(Type modelType)
    {
          if(modelType == typeof(TimeOfDay) || modelType == typeof(TimeOfDay?))
            {
                 return  new TimeOfDayModelBinder();
            } 
           return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

您需要在DependencyResolver/IOC容器中注册它执行此操作(在Global.asax - app start中):

ModelBinderProviders.BinderProviders.Add(new TimeOfDayModelBinderProvider());
Run Code Online (Sandbox Code Playgroud)


Ren*_*ené 1

根据@LukeH 的评论,这似乎是必要的。我想这也是有道理的,因为TimeOfDayNullable<TimeOfDay>确实是 CLR 中的两种不同类型。所以我想我必须忍受它。:-)