我有一个ASP.NET MVC应用程序,其中某些资源的处理如下:
/controller/action/id?revision=123
修订参数是可选的:
我的第一次尝试是做这样的事情:
[OutputCache(Duration=10,Location=OutputCacheLocation.Server)]
public Action(string id)
{
long lastRevision = GetLastRevision(id);
return RedirectToAction("Action",
new { Id = id, revision = lastRevision });
}
[OutputCache(Duration=int.MaxValue,Location=OutputCacheLocation.Server)]
public Action(string id, long revision)
{
// ...
}
不幸的是,ASP.NET MVC路由似乎不喜欢方法重载。它希望有一个带有可选参数的Action
方法(即long? revision
),但是我不能为这两种情况指定不同的缓存策略。
如何根据查询字符串的存在选择不同的缓存策略?
答案 0 :(得分:2)
您可以编写自定义方法选择器:
public class RevisionMethodSelectorAttribute : ActionMethodSelectorAttribute
{
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
{
var revision = controllerContext.Controller.ValueProvider.GetValue("revision");
var hasRevisionParam = methodInfo.GetParameters().Any(p => string.Equals("revision", p.Name, StringComparison.OrdinalIgnoreCase));
if (revision != null && !string.IsNullOrEmpty(revision.AttemptedValue) && hasRevisionParam)
{
return true;
}
if ((revision == null || string.IsNullOrEmpty(revision.AttemptedValue)) && !hasRevisionParam)
{
return true;
}
return false;
}
}
然后用它装饰2个动作:
[RevisionMethodSelector]
public ActionResult MyAction(string id)
{
long lastRevision = GetLastRevision(id);
return RedirectToAction("MyAction", new { id = id, revision = lastRevision });
}
[RevisionMethodSelector]
[OutputCache(Duration = int.MaxValue, Location = OutputCacheLocation.Server, VaryByParam = "revision")]
public ActionResult MyAction(string id, long revision)
{
...
}
第一个操作未缓存。如果请求中没有修订参数,它将被拾取,它将简单地重定向到第二个操作。第二个操作缓存很长一段时间,此缓存根据修订参数值(您没有)而变化,如果请求中存在修订参数,则自定义方法选择器将选择该缓存。
答案 1 :(得分:0)
事实证明,我已经解决了这个问题而没有通过使用302重定向来实现它:显然 302响应没有缓存,即使您的控制器上有OutputCache
属性方法!
因此,这两种情况都可以通过单个控制器方法处理,[OutputCache(...)]
属性指定如何处理200个响应。
虽然这现在引出了如果你想要缓存302 ...
该怎么办的问题