0

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

然后我在传递给视图之前在控制器中手动创建 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 中使用它(编辑、创建)的每个控制器类上创建此选择列表。没有真正遵循 DRY,但我不确定更好的方法。

此外,如果我有另一个存储可用于该列的 3 个值的表,答案是否会改变。我不是从上面创建选择列表,而是从查找表中获取值(我们的应用程序中有这两种情况)?

谢谢!

4

1 回答 1

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)
{
    ...
}

或将其注册为全局操作过滤器,在这种情况下,它将应用于您的所有控制器操作。

于 2013-03-08T07:10:21.960 回答