Asp.net mvc 3 内部模型的自定义模型绑定器

Asp.net mvc 3 内部模型的自定义模型绑定器,asp.net-mvc-3,asp.net-mvc-2,custom-model-binder,custom-binding,Asp.net Mvc 3,Asp.net Mvc 2,Custom Model Binder,Custom Binding,我有一个这样的模型: public class MainModel { public string Id {get;set;} public string Title {get;set;} public TimePicker TimePickerField {get;set;} } public class TimePicker { public TimeSpan {get;set;} public AmPmEnum AmPm {get;set;} } var

我有一个这样的模型:

public class MainModel
{
   public string Id {get;set;}
   public string Title {get;set;}
   public TimePicker TimePickerField {get;set;}
}
public class TimePicker 
{
   public TimeSpan {get;set;}
   public AmPmEnum AmPm {get;set;}
}
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
TimePicker
是一个内部模型,如下所示:

public class MainModel
{
   public string Id {get;set;}
   public string Title {get;set;}
   public TimePicker TimePickerField {get;set;}
}
public class TimePicker 
{
   public TimeSpan {get;set;}
   public AmPmEnum AmPm {get;set;}
}
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
我正在尝试为内部模型创建自定义模型绑定:
TimePicker

问题是:如何在自定义模型活页夹中获取值,该活页夹以
TimePicker
model字段的形式提交

如果我试着这样做:

public class MainModel
{
   public string Id {get;set;}
   public string Title {get;set;}
   public TimePicker TimePickerField {get;set;}
}
public class TimePicker 
{
   public TimeSpan {get;set;}
   public AmPmEnum AmPm {get;set;}
}
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
我只是在
值中得到
null

我不知道如何正确地实现模型绑定器

public class TimePickerModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
        {
            throw new ArgumentNullException("bindingContext");
        }
        var result = new TimePicker();

        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (value != null)
        {
            bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);
            try
            {
                //result = Duration.Parse(value.AttemptedValue);
            }
            catch (Exception ex)
            {
               bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex.Message);
            }
        }    

        return result;
    }
}

以下内容适合我

型号:

public enum AmPmEnum
{
    Am, 
    Pm
}

public class TimePicker 
{
    public TimeSpan Time { get; set; }
    public AmPmEnum AmPm { get; set; }
}

public class MainModel
{
    public TimePicker TimePickerField { get; set; }
}
控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MainModel
        {
            TimePickerField = new TimePicker
            {
                Time = TimeSpan.FromHours(1),
                AmPm = AmPmEnum.Pm
            }
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MainModel model)
    {
        return View(model);
    }
}
视图(
~/Views/Home/Index.cshtml
):

模型活页夹:

public class TimePickerModelBinder : IModelBinder
{
    public object BindModel(
        ControllerContext controllerContext, 
        ModelBindingContext bindingContext
    )
    {
        var key = bindingContext.ModelName + "._picker_";
        var value = bindingContext.ValueProvider.GetValue(key);
        if (value == null)
        {
            return null;
        }

        var result = new TimePicker();

        try
        {
            // TODO: instead of hardcoding do your parsing
            // from value.AttemptedValue which will contain the string
            // that was entered by the user
            return new TimePicker
            {
                Time = TimeSpan.FromHours(2),
                AmPm = AmPmEnum.Pm
            };
        }
        catch (Exception ex)
        {
            bindingContext.ModelState.AddModelError(
                bindingContext.ModelName, 
                ex.Message
            );
            // This is important in order to preserve the original user
            // input in case of error when redisplaying the view
            bindingContext.ModelState.SetModelValue(key, value);
        }
        return result;
    }
}
最后在
应用程序\u Start
中注册您的模型活页夹:

ModelBinders.Binders.Add(typeof(TimePicker), new TimePickerModelBinder());

从您的问题来看,不清楚提交了哪些值以及您的视图是什么样子的。还不清楚为什么您需要此模型的自定义模型绑定器,以及它的具体用途。此外,还不清楚您是直接实现了
IModelBinder
,还是对
DefaultModelBinder
进行了子类化。另一件不清楚的事情是,您试图在这个模型绑定器的哪个方法中调用
bindingContext.ValueProvider.GetValue(bindingContext.ModelName)(显然,如果您直接实现IModelBinder,将有一个方法:BindModel)。视图有两个字段:带时间的文本字段和带PM/AM选择的两个单选按钮。我不知道需要实现什么,或者IModelBinder直接实现什么,或者DefaultModelBinder的子类实现什么。很高兴能得到这方面的建议。是的,我称之为BindModel。我在问题中添加了我的binder。有机会看到你的代码吗?你也没有回答我的问题,为什么你需要一个定制的模型活页夹。你到底想达到什么目的?因为它的全系统组件用于挑选时间。我想用model自动绑定它。因为在一端,我得到一个字符串,比如:01:23 PM等等,我需要它来转换成正常时间。当我从数据库中获取时间并且需要它显示在组件中时也是如此。家让事情变得更清楚了。非常感谢。我用了一种不同的方式,但你的回答真的很有帮助。非常感谢。