Получить экземпляр ActionFilterAttribute в методе - PullRequest
4 голосов
/ 11 октября 2010

Я новичок в платформе ASP.NET MVC и столкнулся со следующей проблемой.

Я использую ActionFilterAttribute, чтобы выполнить некоторую рутинную работу до и после запуска метода действия. Проблема в том, что мне нужно получить экземпляр атрибута в методе действия для чтения некоторых свойств, которые были установлены в методе OnActionExecuting. Например

public class SomeController : Controller{

public SomeController(){ }

[Some]
public ActionResult Index(){
    SomeModel = someRepository.GetSomeModel();

    //get instance of some attribute and read SomeProperty

    return View(SomeModel);
}

}


public class SomeAttribute : ActionFilterAttribute{

public int SomeProperty { get; set; }

public SomeAttribute(){ }

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var parameters = filterContext.ActionParameters;
    //Here to set SomeProperty depends on parameters
}

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
        //do some work
}
}

Есть идеи?

Ответы [ 3 ]

2 голосов
/ 11 октября 2010

Атрибуты фильтра должны быть спроектированы как поточно-ориентированные.Инфраструктура не гарантирует, что один экземпляр вашего атрибута фильтра будет обслуживать только один запрос за раз.Учитывая это, вы не можете изменить состояние экземпляра атрибута из методов OnActionExecuting / OnActionExecuted.

Рассмотрите один из них в качестве альтернативы:

  • Используйте HttpContext.Items для хранения значенияв OnActionExecuting, затем прочитайте его из метода действия.Вы можете получить доступ к HttpContext через параметр filterContext , переданный в OnActionExecuting.

  • Поместите свойство в контроллер вместо атрибута, а затем метод OnActionExecuting приведёт контроллер кSomeController и установить свойство непосредственно из этого метода.Это будет работать, так как фреймворк по умолчанию гарантирует, что экземпляры контроллера являются временными;один экземпляр контроллера никогда не будет обслуживать более одного запроса.

1 голос
/ 11 октября 2010

Вариант 1. Ваш ActionFilter может добавить информацию к ViewModel, например,

  filterContext.Controller.ViewData["YourKey"] = "Value to add";

Вариант 2. Вы можете поместить код в базовый класс Controller, который находит все атрибуты, которые были применены к выполняемому методу, и вы можете поместить их в переменную-член, которую затем может использовать метод Action.

, например

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var attrs = filterContext.ActionDescriptor.GetCustomAttributes(true).OfType<Some>();
        ...
    }

Редактировать: И, как другие заметили, попытка изменить атрибут не сработает.

0 голосов
/ 11 октября 2010

Извините, я не верю, что это возможно. Поскольку значение SomeProperty должно основываться на параметрах, отправляемых в конструктор атрибута, его должно быть легко вычислить. Я бы предложил добавить несколько статических методов, чтобы получить значение из действия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...