Выберите политику OutputCache на основе строки запроса - PullRequest
2 голосов
/ 25 февраля 2012

У меня есть приложение ASP.NET MVC, где определенные ресурсы адресуются следующим образом:

/controller/action/id?revision=123

Параметр revision является необязательным:

  • , еслиотсутствует, я делаю 302 редирект на последнюю ревизию.Я хочу, чтобы этот ответ на перенаправление кэшировался только на короткое время или вообще не был.
  • , если он присутствует, я хочу кэшировать ответ в течение длительного времени, потому что любая данная ревизия ресурса является неизменной.

Моей первой попыткой было сделать что-то вроде этого:

[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), но тогда я не смогу указать разные политики кэширования для обоих случаев.

Как выбрать другую политику кэшированияна основании наличия здесь строки запроса?

Ответы [ 2 ]

2 голосов
/ 25 февраля 2012

Вы можете написать собственный селектор метода:

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)
{
    ...
}

Первое действие не кэшируется. Он будет выбран, если в запросе нет параметра ревизии, и он просто перенаправит на второе действие. Второе действие кэшируется в течение очень долгого времени, этот кэш настраивается в соответствии со значением параметра ревизии (которого у вас не было) и будет выбираться селектором пользовательского метода, если в запросе присутствует параметр ревизии.

0 голосов
/ 25 февраля 2012

Оказывается, я уже решил эту проблему, не реализовав ее, используя 302 перенаправления: очевидно, 302 ответа не кэшируются , даже если у вас есть атрибут OutputCache в вашем методе контроллера!

Поэтому оба случая могут быть обработаны одним методом контроллера с атрибутом [OutputCache(...)], определяющим, что делать для 200 ответов.

Хотя теперь возникает вопрос, что делать, если вы хотите кэшировать 302 ...

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