ASP.NET MVC(MVC4)中是否有任何有用的钩子可以让您在调用操作方法之前访问操作方法参数(视图模型),然后(例如,取决于您在操作方法中检查的值)参数)让您阻止调用操作方法,即,将视图模型对象(操作方法参数)转发到另一个操作方法或直接转发到某个视图(即在操作方法中没有任何进一步处理)?
如果您不理解这个问题,请参阅下面的代码示例,它应该说明我正在寻找的代码类型......(虽然我不知道是否真的存在这种接口以及将实现挂钩的可能性MVC 框架)
如果这确实是可能的,我希望看到一个关于如何做到这一点的代码示例的答案(而不仅仅是一个声称“尝试使用方法'ActionFilterAttribute.OnActionExecuting'或'IModelBinder.BindModel'”的人的回应,因为我已经尝试过这些并且无法使其工作)。另外,请尊重我不希望这个帖子成为关于为什么这样做的讨论,而是想看看如何去做。(即,我对与诸如“您实际上想要实现的目标是什么?”或“做您想做的事情可能有更好的事情……”之类的回答进行讨论不感兴趣)
这个问题可以分成三个子问题/代码示例,因为下面我自己的代码示例试图说明:(但希望它们“重构”为使用真实现有类型的真实代码)(显然,下面的每个类型都包含子字符串“有些”是我编造的,正在寻找对应的实物……)
(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);
}