20

NerdDinnersの例に従って、厳密に型指定されたマスター ページを作成することに興味があります。これを実現するために、マスター ページのデータを取得するベース コントローラーを使用します。他のすべてのコントローラーは、このクラスを継承します。同様にViewModels、マスター ページとその他のビューについても同様です。ビューViewModelクラスは、マスター ページのViewModel.

質問

ViewModel子コントローラーは、マスター ページ自体に関連するプロパティを設定せずに、マスター ページのデータがビューに渡されるようにするにはどうすればよいですか?

マスター ページには多数のボタンが表示されます。これらのボタンは XML ファイルで決定されるため、作成するButtonsクラスになります。

MasterPage ViewModel コード スニペット

using System.Collections.Generic;

namespace Site1.Models
{
    public class MasterViewModel
    {
        public List<Button> Buttons{set; get;}
    }
}

意見ViewModel

namespace Site1.Models
{
    public class View1ViewModel : MasterViewModel
    {
        public SomeDataClass SomeData { get; set; }
    }
}

ベースコントローラー

using System.Collections.Generic;
using System.Web.Mvc;
using Site1.Models;

namespace Site1.Controllers
{
    public abstract class BaseController : Controller
    {
        protected MasterViewModel model = new MasterViewModel();

        public BaseController()
        {
            model.Buttons = new List<Button>();
            //populate the button classes (doesn't matter how)
            PopulateButtons(model.Buttons);
        }
    }
}

ビューのコントローラー:

using System.Web.Mvc;

namespace Site1.Controllers
{
    public class View1Controller : BaseController
    {
        public ActionResult Index()
        {
            Models.View1ViewModel viewModel = new Models.View1ViewModel();
            SomeDataClass viewData = new SomeDataClass()
            //populate data class (doesn't matter how)
            PopulateDataClass(viewData);
            viewModel.SomeData = viewData;
            //I WANT TO ELIMINATE THE FOLLOWING LINE!
            viewModel.Buttons = model.Buttons;
            return View("Index", viewModel);
        }
    }
}

マスター ページは を継承しSystem.Web.Mvc.ViewMasterPage<Site1.Models.MasterViewModel>ます。

ビューは を継承しSystem.Web.Mvc.ViewMasterPage<Site1.Models.View1ViewModel>ます。

4

2 に答える 2

17

おそらく基本コントローラー関数を呼び出すことにより、そのタイプのモデルを探し、それに応じてプロパティを設定するアクション実行後のフィルターを作成できます。次に、フィルターを基本クラスに配置すると、すべてのアクションが自動的にフィルターを認識します。

action フィルター属性はコントローラーのを取得し、それをコントローラーの関数ViewModelに渡します。SetModel

using System.Web.Mvc;
using Site1.Controllers;

namespace Site1.Models
{
    public class MasterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            base.OnActionExecuted(filterContext);

            MasterViewModel viewModel = (MasterViewModel)((ViewResultBase)filterContext.Result).ViewData.Model;

            BaseController controller = (BaseController)filterContext.Controller;
            controller.SetModel(viewModel);
        }
    }
}

この機能は に追加されますBaseController:

public void SetModel(MasterViewModel childViewModel)
{
    childViewModel.Buttons = model.Buttons;
}
于 2009-04-20T15:31:19.620 に答える
6

属性を作成するのではなく、Controller.OnActionExecuted をオーバーライドしてそこに初期化コードを配置してみませんか? 少し単純なようです。

于 2009-04-27T04:40:15.760 に答える