使用BindAttribute附加到子类MVC3模型中的白名单

时间:2011-03-19 14:28:49

标签: c# asp.net-mvc reflection binding attributes

我使用白名单将查询字符串/表单值绑定到我的模型。这可以通过以下方式完成:

[Bind(Include = "Size,Color,Age,SizeOfTeeth")]
public class AnimalModel { ... }

但是我说有一个名为ElephantModel的子类模型,我想保留基类的白名单,并为它添加一些派生类的属性。我该怎么做?

我试过了:

[Bind(Include += "TrunkLength,Personality")]
public class ElephantModel : AnimalModel { ... }

但当然这不起作用。我怀疑这实际上是一个“属性”问题,而不是一个“绑定”问题,但我无法弄清楚要使用什么语法。

TIA!马特

2 个答案:

答案 0 :(得分:1)

由于C#中属性的性质,我担心这是不可能的。属性表示在编译时烘焙到结果程序集中的元数据,这意味着它们只能在编译时获取已知的表达式。

我建议您使用一种可能的解决方法是使用视图模型。因此,例如,您将拥有以下视图模型,其中您将仅包含实际应绑定的属性:

public class UpdateElephantViewModel
{
    public int Size { get; set; }
    public string Color { get; set; }
    public int Age { get; set; }
    public int SizeOfTeeth { get; set; }
    public int TrunkLength { get; set; }
    public string Personality { get; set; }
}

如果重用基本视图模型,它也可能如下所示:

public class UpdateAnimalViewModel
{
    public int Size { get; set; }
    public string Color { get; set; }
    public int Age { get; set; }
    public int SizeOfTeeth { get; set; }
}

public class UpdateElephantViewModel : UpdateAnimalViewModel
{
    public int TrunkLength { get; set; }
    public string Personality { get; set; }
}

然后您可以执行以下控制器操作:

[HttpPost]
public ActionResult Update(UpdateElephantViewModel model)
{
    ...
}

最后在视图模型和实际的大象模型之间进行映射。为了简化这两种类型之间的映射,您可以使用AutoMapper

答案 1 :(得分:1)

Subclassing BindAttribute似乎最好,但它标记为密封。那么我想在子类的构造函数中修改属性,但是除非必要,否则它会使用我希望避免的反射。

所以我选择这种方法用于基类:

[Bind(Include = WhiteList)]
public class AnimalModel {

  protected const string WhiteList = "Size,Color,Age,SizeOfTeeth";

}

然后是子类:

[Bind(Include = WhiteList)]
public class ElephantModel : AnimalModel {

  new protected const string WhiteList = AnimalModel.WhiteList + ",TrunkLength,Personality";

}  

不幸的是,这意味着必须为子类重新定义属性(因为您正在修改它)。但这并不重要。