我是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
}
}
有什么想法吗?
答案 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的值必须基于发送到属性构造函数的参数,因此必须易于计算。我建议添加一些静态方法来从动作中获取值。