2016-04-14 2 views
7

У меня есть статический метод по имени GetRole(), который возвращает строковое значение.
Теперь я хочу называть это при использовании параметров атрибута.
, например:Как вызвать метод при использовании параметров атрибутов

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

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

Но компилятор получить ниже сообщение об ошибке:

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

Пожалуйста, помогите мне вызывать метод атрибутов.

+0

Вы не можете. Принимаются только значения параметров, которые могут быть разрешены во время компиляции. –

+1

Атрибуты не хранятся как код, они хранятся как метаданные - поэтому вы можете использовать только ограниченный набор конструктов внутри них. –

ответ

5

Compiler ошибка довольно ясно, вы не можете вызвать любой метод при объявлении атрибута (потому что его значение должно быть известно во время компиляции), но вы можете получить свой собственный пользовательский атрибут, полученный из AuthorizeAttribute выполнять все логики вам нужно. Разве это не то, что мы все сделали, чтобы локализовать друзей до фантастических долгожданных локализованных данных аннотаций?

Доказательство концепции:

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

И потом:

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

Это просто один возможный путь, там вы можете поместить свою собственную логику или просто обновить Roles свойство и делегировать обычным логика просто вызывает base.AuthorizeCore(context). Имейте в виду, что весь ваш код здесь должен быть потокобезопасным.

Если вы работаете со статическими методами, и вы хотите сохранить эту логику внутри контроллера, то вы можете играть вокруг, чтобы принять (например) что-то вроде этого:

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

Заметьте, что вы можете получить доступ к контроллеру и просмотреть имена от context.HttpContext.Request.RequestContext.RouteData.

Затем вызовите такой статический метод. Обратите внимание: если логика действительно сложна и сильно меняется, вы можете захотеть централизовать эту логику и использовать другие инструменты MVC .

1

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

Это факт. Нет пути, аргумент атрибута должен быть константой времени компиляции. Вы не можете вызвать метод.

Что вы можете сделать, это определить константу:

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

Константы (как следует из названия) во время компиляции постоянной, так что вы, возможно, этот способ поможет.

Если вы хотите, чтобы определить значение в время выполнения, это не будет работать, как атрибуты присваиваются во время компиляции.

+0

Для чего это был downvote? Вероятно, потому что я не знаю атрибут «Авторизовать». Но вопрос никогда не утверждал, что речь идет об определенном атрибуте с конкретной реализацией. Даже не знаю, где называется «AuthorizeCore» (как упоминается Адриано Репетти). –

+0

Я проголосую за вас. Я не знаю. –

0

Я использовал свой собственный метод авторизации вошедшего в систему пользователя.

Посмотрите, возможно, это поможет вам.

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

     return true; 
    } 

и проверить, имеет ли пользователь доступ или нет,

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

я также код стандарта построен в авторизации,

, если вам это нужно, просто комментарий ниже.

0

Вы можете сделать так,

этот метод лучше, потому что здесь вы можете передать список ролей быть авторизован, а не одной роли. (Посмотрите ниже, я прошел админа и мастер оба)

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

и разрешить его, у меня есть этот метод.

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

Хмммммм, мое нисходящее, потому что оно ничего не добавляет к существующим ответам и ничего к существующему AuthorizeAttribute (который уже обрабатывает несколько ролей ...), все еще не отвечая на вопрос (вызывая метод ...). По крайней мере, ваш другой ответ взял альтернативный подход (императив вместо декларативного разрешения) –

+0

yes @AdrianoRepetti, может быть, это потому, что мы оба даем ответ в какое-то время ... и я не знаю, что вы дали ответ с той же концепцией. – Bharat

Смежные вопросы