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

发布于 2024-10-22 23:35:37 字数 436 浏览 1 评论 0原文

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

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

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

我尝试过:

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

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

TIA!马特

I use a whitelist to bind querystring/form values to my model. This is done by:

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

But say I have a subclassed Model, called ElephantModel, and I'd like to keep the whitelist from the base class, and add some of the derived class' properties to it. How would I do that?

I tried:

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

But of course that doesn't work. I suspect this is actually more of an "Attributes" question, than a "binding" question, but I can't figure out what syntax to use.

TIA!Matt

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眼前雾蒙蒙 2024-10-29 23:35:37

由于 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

I am afraid this is not possible due to the nature of attributes in C#. Attributes represent metadata that is baked into the resulting assembly at compile time meaning that they can only take expressions known at compile time.

One possible workaround that I would recommend you is to use view models. So for example you would have the following view model in which you would include only the properties that really should be bound:

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; }
}

which also might look like this if the base view model would be reused:

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; }
}

and then you could have the following controller action:

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

and finally map between the view model and the actual Elephant model. To ease the mapping between those two types you could use AutoMapper.

Hello爱情风 2024-10-29 23:35:37

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

}  

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

Subclassing BindAttribute seems best, but its marked sealed. So then I thought to modify the attribute in the subclass' constructor, but that uses reflection which I'd prefer to avoid unless necessary.

So I chose this approach for the base class:

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

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

}

Then for the subclass:

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

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

}  

Unfortunately this means the attribute must be REdefined for the subclass (as you are modifying it). But that's no biggie.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文