DataAnnotation验证和自定义模型绑定器 [英] DataAnnotation Validations and Custom ModelBinder

查看:96
本文介绍了DataAnnotation验证和自定义模型绑定器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在运行一些实验用ASP.NET MVC2,并已运行到一个有趣的问题。

I've been running some experiments with ASP.NET MVC2 and have run into an interesting problem.

我想定义将被用作在MVC应用模型中的对象周围的接口。此外,我想在功能上通过标记该接口与验证属性成员利用新DataAnnotation的。

I'd like to define an interface around the objects that will be used as Models in the MVC app. Additionally, I'd like to take advantage of the new DataAnnotation functionally by marking up the members of this interface with validation attributes.

所以,如果我的网站有一个照片的对象,我会定义以下接口:

So, if my site has a "Photo" object, I'll define the following interface:

public interface IPhoto 
{ 
 [Required]
 string Name { get; set; }

 [Required]
 string Path { get; set; }
}

我会定义以下实现:

And I'll define the following implementation:

public class PhotoImpl : IPhoto 
{
 public string Name { get; set; }
 public string Path { get; set; }
}

我的MVC应用程序控制器可能包括像方式:

My MVC App controller might include methods like:

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:

And finally, in order to bind PhotoImpls to the parameters in these action methods, I might implement the following extensions to the 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);
 }
}

似乎一切都在iPhoto中执行[必填]的属性除了在我的控制器的ModelState.IsValid财产似乎并没有注意到无效值伟大的工作,(比如,空)。

Everything appears to working great, except that the ModelState.IsValid property in my controller doesn't appear to notice invalid values (say, null) in the [Required] properties of the IPhoto implementation.

我怀疑是我忽略了设置国家一些重要的一块,我ModelBinder的实现。任何提示?

I suspect that I'm neglecting to set some important piece of state in my ModelBinder implementation. Any hints?

推荐答案

检查源System.Web.MVC.DefaultModelBinder后,它看起来像这样可以用一个稍微不同的方法来解决。如果我们更多地依赖于基本实现BindModel的,看起来我们可以构造一个PhotoImpl对象,同时还拉动了验证从iPhoto属性。

After inspecting the source for System.Web.MVC.DefaultModelBinder, it looks like this can be solved using a slightly different approach. If we rely more heavily on the base implementation of BindModel, it looks like we can construct a PhotoImpl object while still pulling the validation attributes from IPhoto.

是这样的:

public class PhotoModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (bindingContext.ModelType == typeof(IPhoto))
        {
            ModelBindingContext newBindingContext = new ModelBindingContext()
            {
                ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(
                    () => new PhotoImpl(), // construct a PhotoImpl object,
                    typeof(IPhoto)         // using the IPhoto metadata
                ),
                ModelState = bindingContext.ModelState,
                ValueProvider = bindingContext.ValueProvider
            };

            // call the default model binder this new binding context
            return base.BindModel(controllerContext, newBindingContext);
        }
        else
        {
            return base.BindModel(controllerContext, bindingContext);
        }
    }
}

这篇关于DataAnnotation验证和自定义模型绑定器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆