在方法中获取ActionFilterAttribute的实例

时间:2010-10-11 18:12:56

标签: asp.net-mvc attributes

我是ASP.NET MVC平台的新手,我遇到了以下问题。

我正在使用ActionFilterAttribute在操作方法运行之前和之后执行一些常规工作。问题是我需要在action方法中获取属性的实例来读取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 个答案:

答案 0 :(得分:2)

过滤器属性必须设计为线程安全的。该框架不保证filter属性的单个实例一次只能为一个请求提供服务。鉴于此,您不能在OnActionExecuting / OnActionExecuted方法中改变属性实例状态。

将其中一种视为替代方案:

  • 使用HttpContext.Items将值存储在OnActionExecuting中,然后从action方法中读取它。您可以通过传递给OnActionExecuting的 filterContext 参数访问HttpContext。

  • 将属性放在控制器而不是属性上,然后让OnActionExecuting方法将控制器强制转换为SomeController,并直接从该方法中设置属性。这将起作用,因为框架默认保证控制器实例是瞬态的;单个控制器实例永远不会为多个请求提供服务。

答案 1 :(得分:1)

选项1:您的ActionFilter可以向ViewModel添加信息,例如

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

选项2:您可以将代码放在基础Controller类中,该类找到已应用于正在执行的方法的所有属性,并且可以将它们放在Action方法可以的成员变量中使用

e.g。

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

编辑:正如其他人所说,尝试改变该属性是行不通的。

答案 2 :(得分:0)

对不起,我不相信这是可能的。由于SomeProperty的值必须基于发送到属性构造函数的参数,因此必须易于计算。我建议添加一些静态方法来从动作中获取值。