ASP.NET MVC 4, wie der Zugriff/ändern der view-model-Objekt (und die Ansicht ändern und die action-Methode), bevor es als action-parameter der Methode?
Ist es nützlich, Haken in ASP.NET MVC (MVC4), das lassen Sie Zugriff auf die Action-Methode-parameter (View-Modell), bevor die action Methode wird aufgerufen, und dann auch noch (z.B. je nach dem Wert von etwas, das Sie bei der Prüfung in der action-Methode-parameter) können Sie verhindern, dass die action-Methode aufgerufen wird, d.h. statt "vorwärts" das view-model-Objekt (action method parameter) auf einen anderen action-Methode oder direkt anzeigen (also ohne weitere Verarbeitung in einer action-Methode) ?
Wenn Sie nicht verstehen, die Frage, bitte siehe code-Beispiel unten, die illustrieren sollten die Art von code, ich bin auf der Suche nach...
(obwohl ich weiß nicht, ob es tatsächlich existiert eine solche Art der Schnittstelle und die Möglichkeit, ein Haken, eine Umsetzung in das MVC-framework)
Wenn dies tatsächlich möglich wäre, würde ich mag, um zu sehen, eine Antwort mit code Beispiel darüber, wie Sie es tun (und nicht nur eine Antwort mit jemandem, der behauptet, dass z.B. "versuchen Sie es mit Methode 'ActionFilterAttribute.OnActionExecuting' oder 'IModelBinder.BindModel' ", weil ich bereits versucht, und konnte nicht damit es funktioniert).
Auch, bitte beachten Sie, dass ich nicht wollen, dass dieser thread zu einer Diskussion über WARUM, es zu tun, aber wollen, um zu sehen WIE, es zu tun.
(d.h. ich bin nicht daran interessiert, in Gesprächen mit Antworten wie "Was bist du eigentlich versucht zu erreichen?" oder "Es gibt wahrscheinlich bessere Dinge zu tun, was Sie wollen...")
Die Frage kann aufgeteilt werden in drei Unterfragen/code-Beispiele, die wie meine eigenen code-Beispiele unten versuchen zu verdeutlichen:
(aber möchte Sie "Refactor" in REAL code mit der Nutzung des real-existierenden Arten)
(natürlich, jede Art unten enthält den substring "Einige" ist etwas, was ich habe, und ich bin auf der Suche nach den entsprechenden realen Sache ...)
(1) Beispiel, wie man Zugriff auf (und möglicherweise ändern) view-model-Objekte (action method Parameter) in einem generischen, bevor die eigentliche action-Methode aufgerufen wird, mit dem view-model-Objekt parameter.
Die Art von code, Beispiel ich Suche wäre wahrscheinlich ähnlich unter, aber nicht wissen, welche Art von Schnittstelle Sie verwenden und wie, um es zu registrieren, um in der Lage sein, etwas zu tun, wie unten:
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) Beispiel dafür, wie um zu verhindern, dass die gezielte action-Methode ausgeführt wird, und stattdessen ein anderes aufrufen-Aktion-Methode.
Das Beispiel ist eine Erweiterung des obigen Beispiels, wie so etwas wie unten:
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) Beispiel dafür, wie um zu verhindern, dass die normalen action-Methode ausgeführt wird und anstatt nach vorne das view-model-Objekt auch direkt zu einer Ansicht, ohne jede weitere Verarbeitung.
Beispiel wäre eine Erweiterung der ersten obigen Beispiel, mit so etwas wie unten:
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);
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
Könnten Sie eine Aktion, filter und überschreiben Sie die
OnActionExecuting
Veranstaltung:Nun wollen wir sehen, was nützliche Informationen, die Sie extrahieren konnte aus dieser
filterContext
argument übergeben wird dieser Methode. Die Immobilie, die Sie suchen sollten, heißtActionParameters
und stellt eineIDictionary<string, object>
. Wie der name schon sagt, diese Eigenschaft enthält alle Parameter, die übergeben werden, um die controller-Aktion, die durch name und Wert.Also nehmen wir an, dass Sie über die folgenden controller-action:
Hier ist, wie Sie den Wert abrufen des Ansicht-Modell nach Modell-Bindung:
Schauen wir uns jetzt den zweiten Teil Ihrer Frage. Wie Kurzschluss, der controller-Aktion und leiten Sie zu einer anderen Aktion?
Umgesetzt werden könnte dies durch die Zuweisung eines Wertes an die
Result
Eigenschaft:oder zum Beispiel Sie sich entscheiden, zu Kurzschluss, die Ausführung des controller-Aktion und direkt Rendern einer Ansicht:
oder Sie können entscheiden, das Rendern einer JSON-Ergebnis:
Wie Sie also sehen können sind die Möglichkeiten unbegrenzt, was Sie tun können.
Habe ich experimentiert mit dem code in der Antwort durch den Nutzer Darin Dimitrov, und die ersten und Dritten Teile der Antwort richtig sind.
(Obwohl für andere, die vielleicht diesen thread und interessiert sein, kann ich klarstellen, dass in der ersten Antwort das "Modell" scheint nicht zu
eine hardcoded-Schlüsselwort immer für das Modell, aber zu haben scheint, entsprechen die gewählten Namen der action-Methode-parameter.
In anderen Worten, wenn Sie stattdessen die Methode Signatur
dann im action-filter, den Sie verwenden müssen,
)
Bezug auf die zweite Antwort, die die Verwendung von 'RedirectToRouteResult' auslösen wird, eine neue http-Anfrage (die nicht gewünscht war wie ich bereits in der zweiten code-Beispiel von mir).
Ich fand einen anderen Weg, der "ändern" action-Methode, indem Sie wirklich aufrufen, es explizit:
Der obige code scheint tatsächlich so zu verhindern, dass die ursprünglich gezielte Aktion-Methode immer aufgerufen, d.h. wenn ich einen breakpoint in der Methode annotate '[MyActionFilter] " die Ausführung nie in diese Methode.
In der Regel ist es wohl nicht erwünscht zu fest einem controller wie oben, aber anstelle Reflexion könnten zum Beispiel verwendet werden, wie unten mit dem thirdpart Bibliothek "fasterflect":
(für diejenigen, die wollen, extrahieren Sie die Namen der aktuellen target-controller-und action-Methode, bei der Implementierung von Logik, um zu bestimmen, den controller, den Sie aufrufen möchten, können Sie diesen code verwenden Sie in den filter:
)
Ich denke, es fühlt sich ein wenig umständlich zu instanziieren und aufrufen-Controller wie oben und würde es bevorzugen, ändern Sie die target-controller und die action-Methode in einer anderen Weise, wenn möglich ?
So, bleibt noch die Frage, ob es noch (in MVC 4 final version) keine Möglichkeit der Umleitung/Weiterleitung Ausführung "intern" (ohne eine neue http-Anforderung ausgelöst wird, als mit 'RedirectToAction') auf dem server ?
Grundsätzlich ich glaube, ich bin hier nur auf der Suche nach so etwas wie "Server.Transfer", die verwendet wurde, mit ASP.NET Web-Formulare (und auch die alten, klassischen ASP-ich glaube, dass könnte die gleiche Sache).
Habe ich gesehen, ältere Frage/Antworten zu diesem Thema mit Menschen, die der Durchführung dieses Verhalten selbst mit einigen "TransferResult" Klasse auf Ihre eigene, aber es scheint neigen dazu, gebrochen zu werden ich verschiedene MVC-Versionen.
(siehe zum Beispiel hier für MVC 4 beta: Zum umleiten von MVC action, ohne 301? (mit MVC 4 beta) ).
Ist es wirklich noch nicht eine einfache standard-Lösung (realisiert in MVC-4-Finale) über, wie man eine "interne Umleitung" ohne eine neue http-Anforderung (wie RedirectToAction tut) ?