0

MVC4、EF5を使用して、レガシーデータベースとコードの上に開発します。データベースには、個別の値のセットを持つ列(例:productcolor)があります。値は、「赤」、「緑」、または「青」にすることができます。DB列はvarchar(20)です。データベースを変更できません(はい、「列挙型」について読みましたが、DBにアクセスできません)。

フォームを使用して新しいアイテムを作成/編集するたびに、これら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

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 に答える