使用接口排除模型绑定的属性

时间:2010-12-16 00:57:18

标签: model-view-controller asp.net-mvc-2 validation interface modelbinder

这是我在这里举起的一个例子:http://aspalliance.com/1776_ASPNET_MVC_Beta_Released.5

public ActionResult Save(int id)
{
 Person person = GetPersonFromDatabase(id);
 try
 {
  UpdateMode<IPersonFormBindable>(person)
  SavePersonToDatabase(person);

  return RedirectToAction("Browse");
 }
 catch
 {
  return View(person)
 }
}

interface IPersonFormBindable
{
 string Name  {get; set;}
 int Age   {get; set;}
 string Email {get; set;}
}

public class Person : IBindable
{
 public string Name   {get; set;}
 public int Age    {get; set;}
 public string Email {get; set;}
 public Decimal? Salary  {get; set;}
}

这不会将值映射到属性Salary,但会执行其验证属性,这在执行标准 [Bind(Exclude =“Salary”)]

时不会出现。
[Bind(Exclude="Salary")]
public class Person
{
 public string Name  {get; set;}
 public int Age   {get; set;}
 public stiring Email {get; set;}
 public Decimal? Salary  {get; set;}
}

如何使用此界面模式实现 [Bind(Exclude =“Property”)]

1 个答案:

答案 0 :(得分:2)

以下是我建议您使用的方法:使用视图模型,删除这些接口,不要使用如此多的代码使控制器混乱。因此,您不需要在此特定操作中绑定薪水:很好,请使用针对此视图的专门定制的视图模型:

public class PersonViewModel
{
    public string Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public string Email { get; set; }
}

你的控制器动作:

public ActionResult Save(PersonViewModel person)
{
    _repository.SavePersonToDatabase(person);
    return RedirectToAction("Browse");

    // Notice how I've explicitly dropped the try/catch,
    // you weren't doing anything meaningful with the exception anyways.
    // I would simply leave the exception propagate. If there's 
    // a problem with the database it would be better to redirect 
    // the user to a 500.htm page telling him that something went wrong.
}

如果在另一个操作中您需要薪水,则编写另一个特定于此视图的视图模型。如果重复视图模型之间的某些属性,请不要担心。这正是他们的意思。显然,您的存储库将使用模型而不是视图模型。所以你需要在这两种类型之间进行映射。我建议您使用AutoMapper来实现此目的。

这是我的观点:总是编写专门针对给定视图需求量身定制的视图模型。尽量避免那些包括,排除或有一天它会咬你,有人会添加一些敏感属性,并忘记将其添加到排除列表。即使你使用Include它仍然很难看。