Append to whitelist in a subclassed MVC3 Model, using BindAttribute
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 w开发者_如何学编程hat syntax to use.
TIA!Matt
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.
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.
精彩评论