ASP.NET MVC (MVC4) 中是否有任何有用的挂钩,可以让您在调用操作方法之前访问操作方法参数(视图模型),然后也可以(例如,取决于您在操作方法中检查的内容的值)参数)让您阻止调用操作方法,即将视图模型对象(操作方法参数)转发到另一个操作方法或直接转发到某个视图(即不在操作方法中进行任何进一步处理)?
如果您不明白这个问题,请参阅下面的代码示例,它应该说明我正在寻找的代码类型......
(虽然我不知道是否真的存在这种接口以及将实现挂钩到 MVC 框架的可能性)
如果这确实可能,我希望看到一个带有关于如何执行此操作的代码示例的答案(而不仅仅是某人声称的响应,例如“尝试使用方法'ActionFilterAttribute.OnActionExecuting'或'IModelBinder.BindModel'”,因为我已经尝试过这些但无法使其工作)。
另外,请尊重我不希望这个帖子成为关于WHY想做,但想看看HOW去做吧。
(也就是说,我没有兴趣参与诸如“您实际上想要实现什么目标?”或“做您想做的事情可能有更好的事情......”等回复的讨论。)
这个问题可以分为三个子问题/代码示例,正如我自己的代码示例下面试图说明的那样:
(但希望它们“重构”为REAL使用实际现有类型的代码)
(显然,下面包含子字符串“Some”的每种类型都是我编造的,我正在寻找相应的真实事物......)
(1) 在使用视图模型对象参数调用实际操作方法之前,如何在通用位置访问(并可能修改)视图模型对象(操作方法参数)的示例。
我正在寻找的代码示例可能类似于下面的代码,但不知道要使用哪种接口以及如何注册它才能执行如下所示的操作:
public class SomeClass: ISomeInterface { // How to register this kind of hook in Application_Start ?
public void SomeMethodSomewhere(SomeActionMethodContext actionMethodContext, object actionMethodParameterViewModel) {
string nameOfTheControllerAboutToBeInvoked = actionMethodContext.ControllerName;
string nameOfTheActionMethodAboutToBeInvoked = actionMethodContext.MethodName;
// the above strings are not used below but just used for illustrating that the "context object" contains information about the action method to become invoked by the MVC framework
if(typeof(IMyBaseInterfaceForAllMyViewModels).IsAssignableFrom(actionMethodParameterViewModel.GetType())) {
IMyBaseInterfaceForAllMyViewModels viewModel = (IMyBaseInterfaceForAllMyViewModels) actionMethodParameterViewModel;
// check something in the view model:
if(viewModel.MyFirstGeneralPropertyInAllViewModels == "foo") {
// modify something in the view model before it will be passed to the target action method
viewModel.MySecondGeneralPropertyInAllViewModels = "bar";
}
}
}
}
(2) 如何阻止执行目标操作方法并调用另一个操作方法的示例。
该示例可能是上面示例的扩展,如下所示:
public void SomeMethodSomewhere(SomeActionMethodContext actionMethodContext, object actionMethodParameterViewModel) {
... same as above ...
if(viewModel.MyFirstGeneralPropertyInAllViewModels == "foo") {
actionMethodContext.ControllerName = "SomeOtherController";
actionMethodContext.MethodName = "SomeOtherActionMethod";
// The above is just one example of how I imagine this kind of thing could be implemented with changing properties, and below is another example of doing it with a method invocation:
SomeHelper.PreventCurrentlyTargetedActionMethodFromBecomingExecutedAndInsteadExecuteActionMethod("SomeOtherController", "SomeOtherActionMethod", actionMethodParameterViewModel);
// Note that I do _NOT_ want to trigger a new http request with something like the method "Controller.RedirectToAction"
}
(3) 示例如何阻止执行正常操作方法,而是将视图模型对象直接转发到视图而不进行任何进一步处理。
该示例是上面第一个示例的扩展,如下所示:
public void SomeMethodSomewhere(SomeActionMethodContext actionMethodContext, object actionMethodParameterViewModel) {
... same as the first example above ...
if(viewModel.MyFirstGeneralPropertyInAllViewModels == "foo") {
// the below used razor view must of course be implemented with a proper type for the model (e.g. interface 'IMyBaseInterfaceForAllMyViewModels' as used in first example above)
SomeHelper.PreventCurrentlyTargetedActionMethodFromBecomingExecutedAndInsteadForwardViewModelToView("SomeViewName.cshtml", actionMethodParameterViewModel);
}