2011-01-14 3 views
1

Ich muss Code schreiben, um eine ID in meiner Datenbank eines Projekts zu finden. Benutzer sind mit einem Projekt verbunden, und alle Projekte haben viele Verbindungen zu anderen Objekten, z. B. zu Sitzungen.Parameter von URL im Controller-Konstruktor erhalten

Jetzt muss ich vor dem Ausführen von Aktionen prüfen, ob der Benutzer, der versucht, auf die Sitzung zuzugreifen, mit demselben Projekt verbunden ist, mit dem die Sitzung verbunden ist.

Dazu möchte ich ein [Attribut] auf die Aktionen verwenden. MVC: creating a custom [AuthorizeAttribute] which takes parameters?

Diese Frage und Antwort hat mich begonnen, aber ich habe Probleme mit dem Konstruktor des Controllers mit meinem Project ID

das Ziel zu bekommen, ist, dass ich in jedem Konstruktor einige Code zu schreiben, alle meine Controller von Objekten abhängig von den Projekten, finden Sie die Projekt-ID, und machen Sie es zugänglich (öffentlich), so dass meine [customauthorize] Zugriff auf diese Projekt-ID haben, um zu überprüfen, ob der Benutzer Zugriff hat oder nicht.

Mein Problem:

public class SessionController : Controller { 

    NASDataContext _db = new NASDataContext(); 


    public SessionController() { 
     var test = RouteData; 
     var ses = _db.Sessies.First(q=>q.Ses_ID==1); 
    } 

Wie greife ich auf meine Routedata? RouteData ist null, HttpContext ist null und Request ist null.

Ich brauche die ID in der URL, die in der Routedata ist ...

Antwort

1

Ich würde vorschlagen, diese Prüfung im Modell anstelle des Controllers platzieren. Im Controller müssen Sie jede Aktion, die diese Prüfung erfordert, dekorieren. Denken Sie daran, dass bei jeder Aktion, die Sie anwenden, Code ausgeführt wird, damit Sie ihn wahrscheinlich nicht auf der Controller-Ebene anwenden. Der einfachere Ansatz besteht darin, den Check einmal im Modell zu implementieren, dann haben Sie keine Bedenken in Ihrem Controller für Zugriffsrechte. Dadurch wird das Testen dieser Zugriffsberechtigungsprüfung möglich, da Sie den Test nur an einer Stelle durchführen können.

+0

in der Prüfung Modell. Das ist ein interessanter Ansatz. Wie würde man das machen? Hast du einen Vortrag/Beispiele? Würde ich eine Erweiterungsmethode für das Modell schreiben, oder würde ich, wie bei einer Edit Action GET-Anfrage, den LINQ-Code ändern, der das Objekt erhält, und den Filter dort hinzufügen, was dazu führen wird, dass das Element nicht gefunden wird und benötigt wird einige zusätzliche Prüfungen für eine korrekte Fehlermeldung. – Stefanvds

+0

Es kommt wirklich darauf an, wie das Model implementiert ist. Wenn Sie in Ihren Controller-Aktionen nur auf Linq to SQL zugreifen, haben Sie zwei grundlegende Ansätze und einen Architekturansatz. Der erste macht meinen Rat, und hier würden Sie jede Instanz Ihres Codes ändern, der auf ein Objekt zugreift, für das es eine Zugriffskontrolle gibt. Die zweite besteht darin, die Tatsache zu verwenden, dass L2S-Objekte als partiell generiert werden, und die Überprüfung in das Projekt-Objekt einzufügen. Die letzte ist die beste IMHO, implementieren Sie das Repository-Muster und legen Sie die Überprüfung in das Repository.Viel sauberer, testbarer und wartbarer. – Lazarus

+0

Haben Sie Beispiele für diese zweite Option? Ich habe einige Objekte, die 4lvls tief im 'Baum' sind, der bei Projekten anfängt. Auch unterschiedliche Rollen sind unterschiedlich an ein Projekt gekoppelt. Also, wenn ich Option 2 richtig bekomme, würde man eine Methode hinzufügen, die den aktuellen Benutzer als Parameter nehmen und einen Bool zurückgeben würde, zugänglich oder nicht? Wenn ich diesen Code habe (Modul ist Kind von Project) var mod = _db.Modules.First (m => m.Mod_ID == id); Ich würde dann mod.Project.IsAccessible (Benutzer) aufrufen? Ist das die Art, wie du arbeitest? :) – Stefanvds

1

Dies ist, was ich jetzt getan habe, um es zu beheben, und ich bin ziemlich glücklich darüber.

Modul Partial:

public partial class Module { 
    public string FullName { 
     get { 
      return Mod_Code + " " + Mod_Titel; 
     } 
    } 
    public string ShortName { 
     get { 
      return Mod_Code; 
     } 
    } 
    public bool IsAccessible() { 
     return this.Projecten.IsAccessible(); 
    } 
} 

Projekte Teil:

public partial class Projecten { 
    public string FullName { 
     get { 
      if (Proj_Kortenaam == Proj_Naam) 
       return Proj_Kortenaam; 

      return Proj_Kortenaam + " " + Proj_Naam; 
     } 
    } 
    public string ShortName { 
     get { 
      return Proj_Kortenaam; 
     } 
    } 

    public bool IsAccessible() { 
     return IsAccessible(HttpContext.Current.User); 
    } 

    public bool IsAccessible(IPrincipal user) { 
     //this code checks if the user can access or not 
     return MvcApplication.projectToegankelijk(user, this._Proj_ID); 
    } 
} 

dann in den Modulen Controller

[NonAction] 
    public ActionResult noRights() { 
     ViewData["delError"] = "You have no rights."; 
     return View("Error"); 
    } 

    // 
    // GET: /Modules/Details/5 
    public ActionResult Details(int id) { 
     var mod = _db.Modules.First(q => q.Mod_ID == id); 
     if (mod.IsAccessible()) { 
      return View(mod); 
     } 
     return noRights(); 
    } 

Ich denke, das recht ordentlich funktioniert

:)
+0

Vergiss nicht deine Antwort zu akzeptieren :) – Lazarus