1

5 つのコントローラーに次のメソッドがあります。

    public ActionResult Index(string page, string title) {
        var vm = new BaseViewModel(); 
        vm.Role = GetRoleNumber(User);
        vm.MenuItems = contentService.GetMenuItems("00", vm.Role);
        vm.Menu = pageService.GetMenu(vm.MenuItems, Request.FilePath);

        // difference code here for each controller
    }

すべてのコントローラーは、BaseController というコントローラーを継承しています。

このコードをベース コントローラーに移動して呼び出す方法はありますか? もしそうなら、これを実装する最良の方法は何でしょうか?

4

4 に答える 4

4

これは、Repository パターンの正確な候補です。これらすべてを Repository クラスで作成し、各 ActionResult メソッドでそのメソッドを呼び出すことができます

public void Repository : IRepository
{
   public GetMyBaseViewModel()
   {
    //..implementation here
   }
}

public interface IRepository
{
  BaseViewModel GetMyBaseViewModel();
}

....そしてあなたのコントローラーで:...

public class HomeController : Controller
    {
        //private repository member
        private readonly IRepository _repository;

        //controller constructors
        //injecting the repository here
        public HomeController() : this(new Repository()) 
        {

        }
        public HomeController(IRepository repository)
        {
          _repository = repository;
        }

        //methods that call the repository for the vm data context
        public ActionResult Index()
        {
            var vm = _repository.GetMyBaseViewModel();
            return View();
        }
}
于 2012-09-07T13:54:42.737 に答える
3

ベースコントローラーで抽象ActionResultメソッドを作成できます。

protected BaseViewModel vm;

public ActionResult Index(string page, string title) {
    vm = new BaseViewModel(); 
    vm.Role = GetRoleNumber(User);
    vm.MenuItems = contentService.GetMenuItems("00", vm.Role);
    vm.Menu = pageService.GetMenu(vm.MenuItems, Request.FilePath);

    try
    {
        return IndexSupplemental();
    }
    catch(NotImplementedException ex)
    {
        // Log and move on; the abstract method is not implemented.
    }

    return View();
}

protected abstract ActionResult IndexSupplemental();

次に、すべてのコントローラーがこの抽象メソッドを実装する必要があります。

于 2012-09-07T13:48:43.417 に答える
2

ベースコントローラーのメソッドに移動して、必要なときに呼び出すことができます。

public class BaseController : Controller
{
    protected BaseViewModel _viewModel;

    public void InitializeViewModel() {

        vm = new BaseViewModel(); 
        vm.Role = GetRoleNumber(User);
        vm.MenuItems = contentService.GetMenuItems("00", vm.Role);
        vm.Menu = pageService.GetMenu(vm.MenuItems, Request.FilePath);
    }
}

例:

public class MyController : BaseController
{
    public ActionResult Index(string page, string title)
    {
        InitializeViewModel();

        DoSomething(_viewModel);
    }
}
于 2012-09-07T13:53:14.703 に答える
1

私のプロジェクトでは、ほとんどのアクションが BaseViewModel から継承したビューモデルを返しますが、これには例外があります。だから私がしたことは、ControllerBaseで次のようなものでした:

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
        var authData = GetUserData();
        if (authData != null)
        {
            var result = filterContext.Result as ViewResult;
            if (result != null)
            {
                var vm = result.Model as ViewModelBase;
                if (vm != null)
                {
                    vm.UserId = authData.UserID;
                    vm.UserName = User.Identity.Name;
                }
            }

        }
    }

ViewModel が異なるタイプであることが予想されるため、それ以外の場合にできることは、ControllerBase で次のようなメソッドを作成することです。

これは、あなたが望むことをしません。いくつかの初期化コードを使用して、派生クラスの新しいインスタンスを作成する手法を示しているだけです。

    protected T Command<T>() where T : BaseCommand, new()
    {
        var command = new T();
        command.IP = Request.UserHostAddress;
        if (User != null && User.Identity.IsAuthenticated)
        {

            var authData = GetUserData();
            if (authData != null)
            {
                command.UserId = authData.UserID;

            }
        }
        return command;
    }

次のように使用されます

var command = Command<CreateUserCommand>();
于 2012-09-07T14:01:46.010 に答える