2

我正在开发类似带有步骤(控制器)和用途的向导DerivedModel1DerivedModel2它继承自BaseModel并使用额外的属性扩展它们。模型——只有数据,没有业务逻辑。控制器操作中服务执行的所有逻辑,例如 _step1Service.GetRelated(model.id)。

现在我不仅要验证模型(在这种情况下有ValidationAttribute),还要修复无效数据BaseModel

 public class BaseModel
 {
     public DateTime StartDate {get;set;}
 }

StartDate应该比今天更大。用户可以选择无效日期,而不是验证错误应用程序应该修复此值(重置为默认值?)。

在我的第一次尝试中,我添加了用于验证/更正的服务,StartDate并在每个操作中调用:

public ActionResult Index(DerivedModel1 model)
{
_svc.fixModel(model);

if(!ModelState.IsValid)
{
return View();
}

... do stuff with valid data
}

但不喜欢那样,因为必须将此行添加到每个控制器和操作。然后我将此更正添加到StartDatesetter。它看起来更好,但这打破了流行的 MVC 范式,即所有逻辑都应该在控制器中(或者我可能误解了什么?)我在考虑这个问题的可能解决方案:ActionFilterAttribute,自定义 ModelBinder?但不确定这种方法是否正确以及是否有效。你怎么看?

4

2 回答 2

1

你必须实现 IModelBinder 来实现这一点。

首先像这样定义您的自定义模型绑定器:

public class MyCustomModelBinder : IModelBinder
{
   public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            // Get the raw attempted value from the value provider
            DateTime incomingDate = (DateTime) bindingContext.ValueProvider.GetValue("datefield").AttemptedValue;
            //validate and correct date here ...
            return new BaseModel{ DateMember =  incomingDate };
        }
}

然后注册您的自定义模型绑定器,例如:

protected void Application_Start()
{
       ModelBinders.Binders.Add(typeof (BaseModel), new MyCustomModelBinder());          
}

和你的控制器:

public ActionResult YourAction([ModelBinder(typeof(MyCustomModelBinder )] BaseModel model)
{
      return Content("Ok");
}
于 2012-11-22T18:08:57.493 回答
0

验证和业务规则之间存在差异。对象可以(并且通常应该)负责确保它们本身处于有效状态。

于 2012-11-22T17:54:58.787 回答