我一直在使用以下代码进行一些测试,以尝试和锻炼ActionFilterAttributes的工作方式:
public class TestAttribute : ActionFilterAttribute
{
private string _privateValue;
public string PublicValue { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
_privateValue = DateTime.Now.ToString();
base.OnActionExecuting(filterContext);
}
}
Run Code Online (Sandbox Code Playgroud)
当我在两个并行线程上运行上面的代码时,_privateValue字段会混淆.但是,PublicValue属性不会混淆.
在我看来,ActionFilterAttributes可以跨线程重用,但是根据为公共属性指定的常量创建新实例.我对么?
我在哪里可以找到相关信息?
Dar*_*rov 81
这将取决于ASP.NET MVC的版本,但您不应将实例状态存储在将在不同方法之间重用的动作过滤器中.以下是ASP.NET MVC 3中一个重大更改的引用:
在以前版本的ASP.NET MVC中,除少数情况外,每个请求都会创建操作过滤器.这种行为从来都不是保证行为,而只是一个实现细节,而过滤器的合同是将它们视为无状态.在ASP.NET MVC 3中,过滤器被更积极地缓存.因此,任何不正确地存储实例状态的自定义操作过滤器都可能被破坏.
这基本上意味着动作过滤器的相同实例可以重用于不同的动作,如果你在其中存储了实例状态,它可能会中断.
就代码而言,这意味着你绝对不应该像这样写一个动作过滤器:
public class TestAttribute : ActionFilterAttribute
{
private string _privateValue;
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
_privateValue = ... some calculation
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
// use _privateValue here
}
}
Run Code Online (Sandbox Code Playgroud)
但是你应该这样写:
public class TestAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var privateValue = ... some calculation
filterContext.HttpContext.Items["__private_value__"] = privateValue;
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var privateValue = filterContext.HttpContext.Items["__private_value__"];
// use privateValue safely here
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9397 次 |
| 最近记录: |