【问题标题】:Append to whitelist in a subclassed MVC3 Model, using BindAttribute使用 BindAttribute 附加到子类 MVC3 模型中的白名单
【发布时间】:2011-03-19 14:28:48
【问题描述】:

我使用白名单将查询字符串/表单值绑定到我的模型。这是由以下人员完成的:

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

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

我试过了:

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

但这当然行不通。我怀疑这实际上更像是一个“属性”问题,而不是一个“绑定”问题,但我不知道要使用什么语法。

TIA!马特

【问题讨论】:

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


    【解决方案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)
    {
        ...
    }
    

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

    【讨论】:

    • +1 :我不能低估 ViewModels(当然,它们与视图紧密绑定)与使用通用域模型(又名 poco's)作为视图模型的不同之处。说得好(再次)达林 :)
    • 达林:感谢您的意见。我正在使用具有所有这些属性的输入模型,并执行严格的验证,检查是否发布不足、过度发布、XSS 向量等。这就是我需要 BindAttribute 的原因。至于 AutoMapper,我不喜欢这些工具的魔力,并且尽可能坚持使用老式的 OO。
    • 纯:更喜欢将输入模型接受到我的控制器中,这应该与域逻辑有关。然后控制器创建适当的视图模型并将其传递给视图。再次强调,老式封装,更少魔法,更易于维护。
    【解决方案2】:

    子类化 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";
    
    }  
    

    不幸的是,这意味着必须为子类重新定义属性(当您修改它时)。但这没什么大不了的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-11
      • 2017-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-11
      • 2017-11-02
      相关资源
      最近更新 更多