2

Ich habe eine ASP.NET MVC-Anwendung, wo ich Dienste im Konstruktor initialisieren. Diese Dienste verweisen nur auf ein anderes .dll im Projekt und sind keine WCF-Dienste. Ich habe meinen Code unten angezeigt:Kann ich auf User.Identity.Name im Konstruktor meines Controllers zugreifen? Wenn nicht, was ist die beste Praxis?

[Authorise] 
public class OrderController : Controller 
{ 
    private OrderService _orderService; 

    public OrderController() 
    { 
     _orderService = new OrderLogic(User.Identity.Name); 
    } 

    public ActionResult Search() 
    { 
     //do stuff here including calling _orderLogic.Search(); 
    } 

    public ActionResult GetMyOrders() 
    { 
     //do stuff here including calling _orderLogic.GetMyOrders(); 
    } 

    //more actions here 
} 

public class OrderService 
{ 
    private string _username; 

    public OrderLogic(string username) 
    { 
     _username = username 
    } 

    public List<Order> Search() 
    { 
     //use _username in query here 
    } 

    public List<Order> GetMyOrders() 
    { 
     //use _username in query here 
    } 

    //more methods here 
} 

Die Frage, die ich im obigen Beispiel ist, dass, wenn ich OrderService initialisieren ich im Namen des angemeldeten Benutzers übergeben. In diesem Stadium im MVC-Lebenszyklus ist User.Identitynull.

Ich glaube nicht, dass es eine Möglichkeit gibt, auf den aktuellen Benutzer im Konstruktor zuzugreifen. Ich möchte auch nicht wirklich den Dienst in jeder Aktion initialisieren oder den aktuellen Benutzer an jede Methode übergeben. Ich bin sicher, dass dieses Szenario üblich ist, was ist Best Practice und welche Möglichkeiten habe ich?

+0

Grundlegende Frage: Ist der Benutzer angemeldet? Im Allgemeinen würden Sie Ihre Order-Klasse oder -Methode mit einem [Authorize] -Attribut versehen, um den anonymen Zugriff zu verhindern. –

+0

Ich weiß, dass der Benutzer angemeldet ist. Ich habe nur keinen Zugriff auf User.Identity im Konstruktor eines Controllers (so kann ich OrderService nicht initialisieren). Ich kann in Aktionen auf User.IDentity zugreifen. – user1786107

+0

Versuchen Sie, Ihren Dienst in der Initialisierungsmethode des Controllers zu initialisieren. Dies könnte http://stackoverflow.com/questions/1506254/how-to-get-user-identity-name-from-a-controller helfen. Oder verwenden Sie IoC, um einen Kundendienst in Ihrem Konstruktor hinzuzufügen http://forums.asp.net/t/1467424.aspx?Access+to+User+Identity+in+Controller+constructor –

Antwort

2

Da diese Frage mit dem Tag abhängigkeits Injektion markiert ist, hier ist der richtige Weg, es zu tun mit Constructor Injection. Injizieren Sie den gewünschten Dienst in Ihrem Controller:

public class OrderController : Controller 
{ 
    private OrderService _orderService; 

    public OrderController(OrderService orderService) 
    { 
     _orderService = orderService; 
    } 

    public ActionResult Search() 
    { 
     //do stuff here including calling _orderLogic.Search(); 
    } 

    public ActionResult GetMyOrders() 
    { 
     //do stuff here including calling _orderLogic.GetMyOrders(); 
    } 

    //more actions here 
} 

Compose OrderController Instanzen in Ihrer Anwendung Composition Roo t. Wie in my book im Detail erläutert, mit ASP.NET MVC tun Sie dies IControllerFactory durch die Implementierung (die durch die Ableitung von DefaultControllerFactory am einfachsten ist):

public class CompositionRoot : DefaultControllerFactory 
{ 
    protected override IController GetControllerInstance(
     RequestContext requestContext, Type controllerType) 
    { 
     if (controllerType == typeof(OrderController)) 
     { 
      return new OrderController(
       new OrderService(
        requestContext.HttpContext.User.Identity.Name)); 
     } 

     // handle other Controller types here... 
    } 
} 

IControllerFactory mit SetControllerFactory Ihrer benutzerdefinierten registrieren.