使用MVC4,EF5在遗留数据库和代码之上进行开发。我们在数据库中有一个列(例如productcolor),它具有一组不同的值。值可以是“红色”,“绿色”或“蓝色”。 DB列是varchar(20)。我无法更改数据库(是的,我读过'枚举' - 但无法触及数据库)。
我想创建某种常见对象,每当使用表单创建/编辑新项目时,它总是返回这3个值的选择列表。
现在,我的模型中有几个[NotMapped]类
[NotMapped]
public string ProductColorSelected {
get { return productcolor; }
set { productcolor = value; }
}
[NotMapped]
public IEnumerable<SelectListItem> ProductColors { get; set; }
然后我在传递给视图之前在Controller中手动创建SelectList
product.ProductColors = new[]
{
new SelectListItem { Value = "Red", Text = "Red" },
new SelectListItem { Value = "Green", Text = "Green" },
new SelectListItem { Value = "Blue", Text = "Blue" },
};
和视图
@Html.DropDownListFor(model => model.ProductColorSelected , Model.ProductColors)
这有效但我需要在POST和GET中使用它(编辑,创建)的每个控制器类上创建这个选择列表。不是真的关注干,但我不确定更好的方式。
此外,如果我有另一个表存储了可用于该列的3个值,答案是否会改变。我不是从上面创建选择列表,而是从查找表中获取值(我们的应用程序中有两个场景)?
谢谢!
答案 0 :(得分:1)
一种可能性是编写一个自定义操作过滤器,它将在每个操作后执行并填充模型上的ProductColors属性:
public class PopulateProductColorsAttribute: ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var viewResult = filterContext.Result as ViewResultBase;
if (viewResult == null)
{
// the controller action didn't return a view result => no need to go any further
return;
}
var model = viewResult.Model as SomeModel;
if (model == null)
{
// The controller action didn't pass a model containing the ProductColors property => no need to go any further
return;
}
// now populate the ProductColors property. Of course here you could do a db lookup or whatever
model.ProductColors = new[]
{
new SelectListItem { Value = "Red", Text = "Red" },
new SelectListItem { Value = "Green", Text = "Green" },
new SelectListItem { Value = "Blue", Text = "Blue" },
};
}
}
现在剩下的就是用自定义动作过滤器装饰所有需要它的控制器动作:
[PopulateProductColors]
public ActionResult Index()
{
SomeModel model = ...
return View(model);
}
[PopulateProductColors]
[HttpPost]
public ActionResult Index(SomeModel model)
{
...
}
或将其注册为全局操作过滤器,在这种情况下,它将应用于您的所有控制器操作。