2009-07-03 4 views
2

Wir bauen eine Website mit asp.net mvc. Wir möchten, dass der Benutzer sich leicht registrieren und ein Konto erstellen kann. Es gibt jedoch eine ganz besondere Information, die in seinem Profil eingetragen wird, die wir ihm * nach der Registrierung zeigen wollen und er meldet sich zum ersten Mal an.asp.net MVC, wie umregistrierte Benutzer, die kein Profil auf Seite haben?

Die Logik ist unabhängig von der URL, die getroffen wurde. Wenn der Benutzer authentifiziert ist und kein gültiges Profil hat, leiten Sie ihn zur Seite "Create Profile" um.

Das ganze UI hängt von diesen Profilwahlen ab. Welchen Ansatz sollten wir innerhalb des MVC-Frameworks verwenden, um diesen Workflow für den Besucher zu erzwingen? Die Ideen, die ich mir vorstellen kann, erfordern eine Menge Code-Duplizierung in Controllern usw., also ist es eindeutig eine schlechte Idee.

Wir verwenden Mitgliedschaft für Benutzer, aber Profil ist unsere eigene Implementierung (kein Profilanbieter), die Profildaten mit einer userId verbindet.

Antwort

3

Ich denke, der einfachste Weg, dies zu tun ist entweder ein benutzerdefiniertes AuthorizeAttribute zu erstellen, das bestehende zu erweitern oder ein separates FilterAttribute zu erstellen. Beide werden auf alle Controller angewendet und stellen sicher, dass ein authentifizierter Benutzer ein Profil besitzt. Wenn kein Profil vorhanden ist, leitet der Filter den Benutzer zu der Seite um, auf der das Profil erstellt wurde. Dazu wird die result-Eigenschaft für den Kontext auf RedirectResult für die Profilerstellungsaktion gesetzt. Nur wenn das Profil existiert und vollständig ist, würde der Filter dem Benutzer ermöglichen, mit der gewünschten Aktion fortzufahren.

Alternativ können Sie einen Basiscontroller erstellen, der OnActionExecuting überschreibt und die gleiche Aufgabe ausführt. Ich bevorzuge den Attributmechanismus, da dieser flexibler ist, d. H. Sie können einige öffentliche Aktionen haben, die ohne das Profil verfügbar sind (einschließlich der Profileinstellungsaktion).

+0

Ich denke, dass es ein großer Aufwand ist, den gleichen Actionfilter immer wieder anwenden zu müssen, wenn man weiß, dass man das immer tun will. Ich werde dies in entweder mit einem Basis-Controller tun (dann müsste ich alle meine Controller erben stattdessen, oder?) Oder gehen Sie in die begin-Anforderung der global.asax. –

+0

Sie können den Filter auf der Controller- oder Aktionsebene anwenden. Wenn es auf der Controller-Ebene angewendet wird, ist es im Grunde dasselbe, wie es im Basis-Controller zu tun ist. Sobald Sie mehrere verschiedene Filter haben, die nicht immer zutreffen, werden Sie die Flexibilität des Filtermechanismus zu schätzen wissen.Nur wenn es wirklich eine globale Aktion ist, würde ich den Basis-Controller-Mechanismus empfehlen. In Ihrem Fall könnte es gelten. – tvanfosson

+0

Danke für Ihre Antworten. Es sieht in der Tat so aus, als wäre es etwas ganz Besonderes, das ich durchsetzen muss, wo auch immer meine registrierten Benutzer hinkommen. Ich denke, es ist ein Preis für die zusätzliche Benutzerfreundlichkeit, die Benutzer nicht zu sehr mit der Registrierung zu belasten. Die Verwendung eines benutzerdefinierten Basis-Controllers erfordert, dass alle Controller, die diese Überprüfung erzwingen müssen, den benutzerdefinierten Ctrler erweitern müssen. Wäre es nicht einfacher, Logik in Global.asas zu setzen, wie xandy es vorschlägt? –

0

Versuchen betrachten Action und FilterAttribute wenn nicht die meisten Seiten so tun müssen, oder aber, Sie tatsächlich diese Umleitung Logik setzen kann Global.asax (in denen Begin Anfrage oder ähnliche Ereignisse)

2

meine eigene Frage zu beantworten: Am Ende habe ich einen benutzerdefinierten actionFilter erstellt. Am Anfang habe ich den Pfad der Unterklasse [authorize] in [AuthorizeCheckProfile] genommen. Aber dann stellte ich fest, dass der Anwendungsfall falsch war: Ich wollte nicht, dass die nur eingeloggten Teile meiner Site auf die Create-Profilseite umgeleitet wurden, wenn kein Benutzerprofil existierte. Ich wollte jede Seite meiner Website auf diese Seite umleiten, wenn es ein angemeldeter Benutzer ohne Profil ist. Der einzige Ort, den ich nicht überprüfen möchte, ist im eigentlichen Profil-Create. Hier ist der Code:

public class AssertProfileAttribute : ActionFilterAttribute { 
    public AssertProfileAttribute() { 
    } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) { 
     if (filterContext.HttpContext.Request.IsAuthenticated == false) 
      return; 
     //we have a user, but does he have a profile? 
     if (filterContext.HttpContext.Session["UserProfile"] == null) { //not in the session 
      IUnityContainer container = filterContext.HttpContext.Application["container"] as IUnityContainer; 
      Profile hasProfile = container.Resolve<IProfileRepository>().GetUserProfile(Membership.GetUser()); 
      if (hasProfile == null) { 
       //we have to redirect to the create profile 
       string returnURL = filterContext.HttpContext.Request.AppRelativeCurrentExecutionFilePath; 
       filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Profile", action = "Create", returnTo = returnURL })); 
      } else { 
       //he has a profile but we haven't put it in session yet 
       filterContext.HttpContext.Session["UserProfile"] = hasProfile; 
      } 
     } 
    } 
} 

Es hat den Nebeneffekt, dass sie das Profil in einem Sitzungsschlüssel speichern. Auf diese Weise kann es leicht abgerufen werden, sodass bei jeder Anfrage mit anderen benutzerdefinierten Filtern weitere Rollenüberprüfungen stattfinden können. Die Implementierung verwendet Unity und Repositories für den Datenbankzugriff.

Ein großes Dankeschön an die Gemeinde.

Verwandte Themen