我一直在使用ASP.NET MVC2进行一些实验,并遇到了一个有趣的问题.
我想在MVC应用程序中定义将用作模型的对象周围的接口.另外,我想通过使用验证属性标记此接口的成员来在功能上利用新的DataAnnotation.
所以,如果我的网站有一个“Photo”对象,我将定义以下界面:
public interface IPhoto { [required] string Name { get; set; } [required] string Path { get; set; } }
我将定义以下实现:
public class PhotoImpl : IPhoto { public string Name { get; set; } public string Path { get; set; } }
我的MVC App控制器可能包含以下方法:
public class PhotoController : Controller { [HttpGet] public ActionResult CreatePhoto() { return View(); } [HttpPost] public ActionResult CreatePhoto(IPhoto photo) { if(ModelState.IsValid) { return View(); } else { return View(photo); } } }
最后,为了将PhotoImpls绑定到这些操作方法中的参数,我可能会对DefaultModelBinder实现以下扩展:
public class PhotoModelBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext) { if(bindingContext.ModelType == typeof(IPhoto)) { IPhoto photo = new PhotoImpl(); // snip: set properties of photo to bound values return photo; } return base.BindModel(controllerContext,bindingContext); } }
除了我的控制器中的ModelState.IsValid属性似乎没有注意到IPhoto实现的[required]属性中的无效值(例如,null)之外,所有内容似乎都运行良好.
我怀疑我忽略了在我的ModelBinder实现中设置一些重要的状态.任何提示?
解决方法
我遇到过同样的问题.答案是在您的自定义模型绑定器中覆盖BindModel(),而不是重写CreateModel()…
protected override object CreateModel(ControllerContext controllerContext,ModelBindingContext bindingContext,System.Type modelType) { if (modelType == typeof(IPhoto)) { IPhoto photo = new PhotoImpl(); // snip: set properties of photo to bound values return photo; } return base.CreateModel(controllerContext,bindingContext,modelType); }
然后你可以让基础BindModel类通过验证来完成它的东西:-)