我在五个控制器中有以下方法:
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的控制器继承。
有没有办法可以将此代码移动到我的基本控制器并调用它?如果是这样,那么实现这个的最佳方法是什么?
答案 0 :(得分: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();
}
}
答案 1 :(得分: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();
然后每个控制器都必须实现这种抽象方法。
答案 2 :(得分: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);
}
}
答案 3 :(得分:1)
在我的项目中,我的大部分操作都将返回一个从BaseViewModel继承的viewmodel,但是有一些例外。所以我在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>();