1

我在五个控制器中有以下方法:

    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 类中创建所有这些并在每个 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 回答