2016-08-09 32 views
4

Mit einem einfachen Aktionsfilter, der überprüft, ob der Benutzer angemeldet ist und seine Benutzer-ID abruft.Wie übergebe ich eine Variable von einem ActionFilter an eine Controller-Aktion in C# MVC?

public class LoginFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    {  
     // Authenticate (somehow) and retrieve the ID 
     int id = Authentication.SomeMethod(); 
     // Pass the ID through to the controller? 
     ..... 
    } 
} 

Wie kann ich diese ID dann an meine Controller-Aktion weitergeben?

Gibt es ein Äquivalent zum ViewBag, mit dem ich das machen könnte? Oder eine andere Technik, die es mir erlaubt, Variablen und Objekte zwischen dem Filter und der Controller-Aktion zu übergeben?

Antwort

5

Sie zu erhalten können diese ViewData/ViewBag wie:

1.) ViewData

ANMERKUNG: Bei Viewdata benötigen Sie einen Schritt zu tun, die Sie auf typ ist haben ECAST es

public class LoginFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    {  
     // Authenticate (somehow) and retrieve the ID 
     int idValue = Authentication.SomeMethod(); 

     // Pass the ID through to the controller? 
     filterContext.Controller.ViewData.Add("Id", idValue); 
    } 
} 

Und dann in Reglerfunktion

[LoginFilter] 
public class Dashboard : Controller 
{ 
    public ActionResult Index() 
    { 
     // I'd like to be able to use the ID from the LoginFilter here 
     int id = (int)ViewData["Id"]; 
    } 
} 

2.) ViewBag

public class LoginFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    {  
     // Authenticate (somehow) and retrieve the ID 
     int idValue = Authentication.SomeMethod(); 

     // Pass the ID through to the controller? 

     filterContext.Controller.ViewBag.Id = idValue; 
    } 
} 

und anschließend in Controller

[LoginFilter] 
public class Dashboard : Controller 
{ 
    public ActionResult Index() 
    { 
     // I'd like to be able to use the ID from the LoginFilter here 
     int id = ViewBag.Id; 
    } 
} 
+0

Danke, obwohl ich TempData (wie von @ Luiso's Antwort vorgeschlagen) beendet habe, anstatt ViewBag oder ViewData, deins gibt die besten Details, wie man es tatsächlich benutzt, zusammen mit Beispielen, und die Technik ist die gleiche für den ViewBag wie für TempData. Ich denke, dass dies Temporäre Daten sind und nicht irgendetwas, was für die Ansicht gedacht ist. Daher ist es sinnvoller, TempData zu verwenden –

4

Ich glaube, ActionExecutingContext enthält eine Referenz auf den rufenden Controller. Dies würde wahrscheinlich mit einer benutzerdefinierten Controller-Klasse kombiniert werden, die von der Basisklasse Controller abgeleitet wurde, um dann die id als Instanzvariable des Controllers zu speichern.

Individuelle Steuerung

Public Class MyController : Controller 
{ 
    Public int Id {get;set;} 
} 

LoginFilter

public class LoginFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    {  
     // Authenticate (somehow) and retrieve the ID 
     int id = Authentication.SomeMethod(); 
     ((MyController)filterContext.Controller).Id = id; 
     //Assign the Id by casting the controller (you might want to add a if ... is MyController before casting) 
    } 
} 

-Controller

[LoginFilter] 
public class Dashboard : MyController 
{ 
    public ActionResult Index() 
    { 
     //Read the Id here 
     int id = this.Id 
    } 
} 
+0

Ich mag die Logik dieser Lösung , indem sie die ID direkt anlegt ly in den Controller und ist ziemlich "ordentlich", aber entschieden, damit nicht zu gehen, weil die tatsächliche Implementierung für jeden, der den Code später hält, ein wenig undurchsichtig erscheint - die ID scheint einfach magisch ohne Erklärung gesetzt zu werden. –

+0

Fair Kritik, danke –

6

können Sie die ViewBag verwenden, indem Sie:

filterContext.Controller.ViewBag.Id = id; 

das sollte es tun, sobald Sie filterContext.Controller tun haben Sie Zugriff auf alle Felder darin wie TempData sowie.

Auch so, wenn Sie OWIN verwenden dann vielleicht einen Benutzer id bekommen könnten Sie die Controller.User verwenden, die eine Verlängerung Methode hat die Id und Eigenschaften zu erhalten, die meist anderen Standarddaten wie Name usw.

+0

Hmm, das scheint wie eine saubere Lösung.Logischerweise ist die Verwendung des ViewBag wahrscheinlich nicht sinnvoll, aber TempData ist wahrscheinlich ein guter Platz dafür. Ich benutze OWIN nicht (oder zumindest nicht für diesen Teil des Projekts, da wir Authentifizierungstechniken mischen). –