Frage

Ich habe eine ähnliche Frage zu stellen, aber verwirrte den Titel und niemand würde es verstehen. Da ich jetzt bin in der Lage, die Frage genauer zu fragen, habe ich beschlossen, es in einer neuen Frage neu zu formulieren und die alten zu schließen. Sorry dafür.

Also, was ich tun möchte, ist Daten übergeben (meine benutzerdefinierten Spitznamen wie in der db gespeichert) an die LoginUserControl. Dieses Login wird von der Master-Seite über Html.RenderPartial () gemacht, so, was ich wirklich brauchen, um zu tun ist, um sicherzustellen, dass, sagen Viewdata [ „UserNickname“] bei jedem Anruf vorhanden ist. Aber ich will nicht Viewdata [ „UserNickname“] in jeder und jede Aktion eines jeden Controller zu bevölkern, so habe ich beschlossen,

War es hilfreich?

Lösung

Meine Vermutung wäre, dass der Basiskonstruktor des Controllers ist nicht im User-Füllung, sondern dass es nur bekannt ist, später, wenn die Controller für den Controller eingestellt ist. Sie sollten dies in der Dokumentation überprüfen über den Lebenszyklus einer MVC-Anwendung, (die ein hier wird wahrscheinlich tun, obwohl es ein bisschen veraltet sein könnte, da es für die Preview-Version) ist, oder überprüfen sie einfach den Quellcode von MVC.

aus dem Code, den ich von MVC (auch eine Preview-Version, aber das sollte in Ordnung sein): (In Controller)

 public IPrincipal User {
            get {
                return HttpContext == null ? null : HttpContext.User;
            }
        }

...

public HttpContextBase HttpContext {
        get {
            return ControllerContext == null ? null : ControllerContext.HttpContext;
        }
    }

Ich sehe nicht, en eine Implementierung eines Standardkonstruktor im Code. Das würde beweisen, dass der Controller zum Zeitpunkt der Konstruktion null ist.

So können Sie Ihren Code ausführen sollte woanders.

Andere Tipps

Die Antwort auf dieses Problem ist eigentlich ganz einfach. Ich kann den Code aus dem Konstruktor aus Gründen ausführen von Raimond wiesen darauf hin, aber ich kann es außerhalb des Konstruktor tun.

Also, was ich tat, war zwingenden OnActionExecuting () in der Basis-Controller-Klasse (habe ich ein benutzerdefiniertes Attribut für sie, aber nur die Methode überschrieben sollte auch funktionieren) und dann von dort meinen Benutzer Lookup.

Jetzt funktioniert es wie erwartet und ich habe keinen wiederholten Code.

Die User-Eigenschaft wird nicht zugewiesen, bis die Controller-instanziiert wurde, aber Sie können mit frühem Zugriff von Ihrem Konstruktor gewinnen:

System.Web.HttpContext.Current.User

Können Sie greifen diese mit so etwas wie:

HttpContext currentContext = HttpContext.Current;
string userName = currentContext.User.Identity.Name;

Oder ist die Httpcontext immer leer ??

Könnten Sie setzen die Httpcontext durch den Konstruktor der abstrakten Klasse? und es auf diese Weise benutzen?

Danke Raimond. Ich war zu müde, das Offensichtliche zu sehen. @Keeney: Ja der Kontext ist immer null. Raimond wies darauf hin, warum. Trotzdem danke, ich sah nicht, warum auch: -)

Meine aktuelle Arbeitslösung (wenn auch nicht das, was ich wollte) ist ein Attribut, das ich verwende, um alle Aktionen meines Controller dekorieren. Hier ist die Umsetzung:

public class MasterPageDataAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
            IUserRepository _repUser = RepositoryFactory.getUserRepository();
            IPrincipal siteUser = filterContext.Controller.ControllerContext.HttpContext.User;
            User loggedInUser = null;

            if (siteUser == null || siteUser.Identity.Name == null)
            {
                //do nothing
            }
            else
            {
                loggedInUser = _repUser.findUserById(siteUser.Identity.Name);
            }
            filterContext.Controller.ViewData["LoggedInUser"] = loggedInUser ?? new User { Nickname = "Guest" };
        }
    }

Ich werde darüber nachdachte, wie dieser Code in einer Weise ausgeführt zu bekommen, die das DRY-Prinzip folgt, da Attribute für die Verwendung auf jeden Fall heißt, sich zu wiederholen. Vielleicht eine Art von Interceptor ( interessante Idee ) oder Haken könnte helfen.

Prost für die.

Ich tue dies in einer Base Implementierung und es funktioniert wie erwartet.

public abstract class BaseController : Controller
{
    public bool LoggedOn
    {
        get { return User.Identity.IsAuthenticated; }
    }
}

Das gibt immer wahr oder falsch für mich so User != null

zu Masterfu: Ich habe etwas ähnlich mit Ihrer Hilfe wünschen, dass letztere Besucher helfen können. In meinem Fall muss ich reposiotry von Controllern für unterschiedliche Benutzer erstellen, noch im Konstruktor von Controllern (Haupt-) Der Nutzer ist nicht bereit. Also habe ich ein Attribut für Controller:

[CreateRepositoryByUser]
public class MFCController : Controller
{
    protected MFCRepository _repository
    {
        get { return ViewData["repository"] as MFCRepository; }
    }
...

die _repository, in der Tat, ist nicht eine private Variable der Steuerung, sondern somethign erstellen, indem Sie das Attribut:

public class CreateRepositoryByUser : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        CreateRepository(filterContext);
    }

    public static void CreateRepository(ActionExecutingContext filterContext)
    {
        if (filterContext.Controller.ViewData["repository"] == null)
        {
            filterContext.Controller.ViewData["repository"] =
                MFCRepository.CreateMFCRepository(filterContext.Controller.ControllerContext.HttpContext.User);
        }
    }
}

Ich habe Codes des Endlagers in einem separaten Verfahren zu schaffen, bei, dass andere Attribute verwenden möchten (Prinzipal) Benutzer vor diesem Attribut ausgelöst wird.

von einem Konstruktor Aufruf ist noch zu früh in der MVC-Pipeline.

Bewegen Code OnAuthorization, Sie erhalten autorisierte Benutzer in einem Parameter. Arbeitete für mich!

Von Ihrem Beispiel würde ich so etwas tun:

public abstract class ApplicationController : Controller {
    private IUserRepository _repUser;

    protected override void OnAuthorization(AuthorizationContext filterContext)
    {
        _repUser = RepositoryFactory.getUserRepository();
        var loggedInUser = _repUser.FindById(filterContext.HttpContext.User.Identity.Name); //Problem!
        ViewData["LoggedInUser"] = loggedInUser;
    }


}

Injizieren IPrincipal wenn Sie User im Konstruktor benötigen.

 // startup.cs
 // Inject IPrincipal
 services.AddTransient<IPrincipal>(provider => provider.GetService<IHttpContextAccessor>().HttpContext.User);

Dann fügen Sie als IPrincipal in Ihrem Konstruktor. Beachten Sie, dass sichergestellt ist, werden ClaimsPrincipal mit ASPNET -., Weil das ist, was HttpContext.User ist

ähnliche Frage

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top