Можно ли использовать eTag для кэширования умных клиентов в asp.net MVC, как в Rails? - PullRequest
1 голос
/ 19 сентября 2009

Я нашел в этой заставке ¹ , которую вы можете сделать в Ruby in Rails, лучшее кэширование клиента ² с учетом модели REST + для заполнения eTag. Гораздо умнее, чем визуализировать все тело http, и только после этого вычисляйте eTag, как обычно.

Это свойство может сделать кэширование клиента более ориентированным на модель при использовании GET, поэтому я считаю, что это очень важно для производительности.

Я нигде не видел, чтобы кто-то делал это с помощью asp.net MVC. Было бы так легко, как я видел, как этот парень играл в Rails?

Ответы [ 2 ]

1 голос
/ 19 сентября 2009

eTag - это концепция HTTP в большей степени, чем связанная с какой-либо одной серверной технологией. Я считаю, что RoR может упростить при сравнении с IIS / MVC указание, что определенный файл кэшируется с использованием eTag.

Для IIS / MVC у вас есть два варианта настройки заголовков ответов (которые могут включать настройки eTag):

  1. В диалоговом окне настроек срока действия IIS.
  2. Настройка обработчиков HTTP или аналогичного метода, чтобы вы точно указывали, какие заголовки ответа вы хотите для определенного запроса. Это программный вариант шага № 1. Это необходимо, если вы транслируете содержимое базы данных по проводам, и в этом случае нет никакого реального файла, о котором можно было бы говорить.

Если есть другие способы сделать это, которых я не перечислил, я хотел бы знать о них.

0 голосов
/ 14 марта 2013

Используйте ActionFilterAttribute для обновления ответа через фильтр

public class ETagAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Filter = new ETagFilter(filterContext.HttpContext.Response, filterContext.RequestContext.HttpContext.Request);
    }
}

public class ETagFilter : MemoryStream
{
    private HttpResponseBase _response = null;
    private HttpRequestBase _request;
    private Stream _filter = null;

    public ETagFilter(HttpResponseBase response, HttpRequestBase request)
    {
        _response = response;
        _request = request;
        _filter = response.Filter;
    }

    private string GetToken(Stream stream)
    {
        byte[] checksum = new byte[0];
        checksum = MD5.Create().ComputeHash(stream);
        return Convert.ToBase64String(checksum, 0, checksum.Length);
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        byte[] data = new byte[count];
        Buffer.BlockCopy(buffer, offset, data, 0, count);
        var token = GetToken(new MemoryStream(data));

        string clientToken = _request.Headers["If-None-Match"];

        if (token != clientToken)
        {
            _response.Headers["ETag"] = token;
            _filter.Write(data, 0, count);
        }
        else
        {
            _response.SuppressContent = true;
            _response.StatusCode = 304;
            _response.StatusDescription = "Not Modified";
            _response.Headers["Content-Length"] = "0";
        }
    }
}

оригинал из: Создание фильтра ETag в ASP.NET MVC

...