2016-04-14 23 views
7

Ich habe eine statische Methode mit dem Namen GetRole(), die einen String-Wert zurückgeben.
Jetzt möchte ich das bei der Verwendung von Attributparametern aufrufen.
zum Beispiel:So rufen Sie eine Methode mit Attributen Parameter

[Authorize(Roles = GetRole())] 
public ActionResult Get() 
{ 
} 

public static string GetRole() 
{ 
    return "Admin"; 
} 

Aber Compiler erhalten unter Fehler:

An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type

Bitte helfen Sie mir, ein Verfahren in Attribute zu nennen.

+0

Sie können nicht. Nur Parameterwerte, die zur Kompilierzeit aufgelöst werden können, werden akzeptiert. –

+1

Attribute werden nicht als Code gespeichert, sie werden als Metadaten gespeichert. Aus diesem Grund können Sie nur eine begrenzte Anzahl von Konstrukten darin verwenden. –

Antwort

5

Compilerfehler ist ziemlich klar, können Sie jede Methode nicht aufrufen, wenn ein Attribut deklarieren (weil ihr Wert zum Zeitpunkt der Kompilierung bekannt sein muss), aber Sie können von AuthorizeAttribute ausführen alle Ihre eigenen Attribut, abgeleitet herleiten Logik, die du brauchst. Ist es nicht das, was wir alle gemacht haben, um NameAttribute & Freunde zu lokalisieren, bevor Sie lange auf lokalisierungsbewusste Datenanmerkungen warten?

Proof-of-Concept:

class DynamicAuthorizeAttribute : AuthorizeAttribute { 
    protected bool AuthorizeCore(HttpContextBase context) { 
     // Perform your logic here, eventually update Roles property 
    } 
} 

Und dann:

[DynamicAuthorize] 
public ActionResult Get() { 
    // ... 
} 

Dies ist nur ein Art und Weise, dort können Sie Ihre eigene Logik setzen oder einfach Roles Eigenschaft aktualisieren und delegieren üblichen Logik einfach anrufen base.AuthorizeCore(context). Beachten Sie, dass der gesamte Code hier threadsicher sein muss.

Wenn Sie mit statischen Methoden arbeiten und Sie wollen, dass die Logik in Ihrem Controller halten, dann können Sie spielen, um so etwas zu übernehmen (zum Beispiel):

[DynamicAuthorize(typeof(MyView), nameof(GetRole))] 

Beachten Sie, dass Sie Controller zugreifen können und zeigen Namen von context.HttpContext.Request.RequestContext.RouteData.

Dann rufen Sie solche statische Methode. Beachten Sie, dass, wenn die Logik wirklich komplex ist und stark variiert, Sie diese Logik möglicherweise zentralisieren und andere MVC Werkzeuge verwenden, um dies zu tun.

1

An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type.

Dies ist eine Tatsache. Es gibt keinen Weg herum, ein Attributargument muss Kompilierzeitkonstante sein. Sie können keine Methode aufrufen.

Was Sie können definieren eine Konstante:

public class MyClass 
{ 
    public const string Role = "Admin"; 
    [Authorize(Roles = Role)] 
    public ActionResult Get() 
    { 
    }  
} 

Konstanten sind Zeitkonstante kompilieren (wie der Name schon sagt), so dass Sie vielleicht diese Abhilfe Ihnen hilft.

Wenn Sie einen Wert bei Laufzeit bestimmen wollen, das wird nicht funktionieren, da die Attribute bei Kompilierung zugeordnet sind.

+0

Für was war dieser Downvote? Wahrscheinlich, weil ich das Attribut 'Autorisieren' nicht kenne. Aber die Frage hat nie gesagt, dass es sich um ein spezifisches Attribut mit einer spezifischen Implementierung handelt. Ich weiß nicht einmal, wo 'AuthorizeCore' (wie von Adriano Repetti erwähnt) aufgerufen wird. –

+0

Ich stimme für dich ab. Ich weiß es nicht. –

0

Ich habe meine eigene Methode zum Autorisieren von angemeldeten Benutzer verwendet.

schau es dir an, vielleicht wird es dir helfen.

public static bool GetRole(string Codename) 
    {    
     if (LogInUser == null) 
     { 
      return false; 
     } 

     return true; 
    } 

und zu überprüfen, ob Benutzer Zugriff hat oder nicht,

if (!Utility.GetRole("Admin")) 
      return View("AccessDenied"); 

ich habe auch Code für Standard in Genehmigung gebaut,

, wenn Sie es brauchen, nur unten kommentieren.

0

Sie können wie folgt tun,

diese Methode ist besser, weil man hier die Liste von Rollen passieren kann autorisiert, statt einzelne Rolle zu. (Bei unter Hören Sie, übergeben i admin und Master beide)

[Authorization(Roles = "admin,master")] 
public class MyController : Controller 
{ 
    //Your remaining code. 
} 

und um es zu autorisieren, habe ich diese Methode.

public class Authorization : AuthorizeAttribute 
{ 

public string Roles { get; set; } 

protected override bool AuthorizeCore(HttpContextBase httpContext) 
{ 
    if (User != null) 
    { 
     if (String.IsNullOrEmpty(Roles)) 
     { 
      return true; 
     } 

     string[] split = Roles.Split(','); 

     foreach (UserRole item in User) 
     { 
      if (split.Contains(item.Role.CodeName)) 
      { 
       return true; 
      } 
     } 
     return false; 

    } 
    else 
     return false; 
} 

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
{ 
    filterContext.Result = new HttpUnauthorizedResult(); 
} 
} 
+0

Hmmmmm, mein Downvote, weil es nichts zu bestehenden Antworten hinzufügt und nichts zu dem vorhandenen AuthorizeAttribute hinzufügt (das bereits mehrere Rollen bearbeitet ...), während die Frage immer noch nicht beantwortet wird (durch Aufrufen einer Methode ...). Zumindest hat Ihre andere Antwort eine alternative Herangehensweise (imperativ anstelle der deklarativen Autorisierung) –

+0

ja @AdrianoRepetti, vielleicht liegt das daran, dass wir beide irgendwann eine Antwort geben ... und ich weiß nicht, dass Sie eine Antwort mit demselben Konzept gegeben haben. – Bharat

Verwandte Themen