В последней бета-версии ASP.NET MVC4, как бы вы поддерживали условную поддержку GET через ETag? ActionFilter должен иметь возможность завершить запрос на создание ETag для возвращаемого ресурса, чтобы сравнить его с заголовком If-None-Match в запросе. И затем, независимо от того, был ли входящий ETag в заголовке If-None-Match таким же, как сгенерированный ETag, добавьте сгенерированный ETag в заголовок ответа ETag. Но с ASP.NET MVC4 я понятия не имею, с чего начать. Какие-либо предложения?
Вопрос
Реализация поддержки ETag в ASP.NET MVC4 WebAPI
Ответы
Ответ 1 · рейтинг 16 · Luke Puplett
Лично я не фанат "магии фреймворка" и предпочитаю старый добрый код в веб-методах, иначе мы получим что-то более похожее на WCF, юк.
Итак, в вашем веб-методе Get вручную создайте ответ следующим образом:
var response = this.Request.CreateResponse(HttpStatusCode.OK, obj);
string hash = obj.ModifiedDate.GetHashCode().ToString();
response.Headers.ETag =
new EntityTagHeaderValue(String.Concat("\"", hash, "\""), true);
return response;
Обратите внимание, что ETag, полученный из хэш-кода временной метки, является чисто иллюстрацией слабой системы маркировки объектов. Он также показывает необходимые дополнительные кавычки.
Ответ 2 · рейтинг 9 · Aliostad
Есть ETagMessageHandler в WebApiContrib который делает то, что вам нужно.
ОБНОВИТЬ
Я реализовал кэширование на стороне сервера RFC 2616 в WebApiContrib. Найдите CachingHandler. Подробнее здесь.
Больше обновлений
Это будет активно развиваться и расширяться в рамках CacheCow. Это будет включать как клиентские, так и серверные компоненты. пакеты NuGet будут скоро опубликованы уже опубликованы.
Обработчик CachingHandler WebApiContrib по-прежнему будет поддерживаться, поэтому сообщайте мне о любых ошибках или проблемах.
Ответ 3 · рейтинг 5 · Greg McCoy
Ответ Люка Пуплетта привел меня на правильный путь (+1), но обратите внимание, что вы также должны прочитать ETag на стороне сервера, чтобы избежать отправки всех данных с каждым запросом:
string hash = obj.ModifiedDate.GetHashCode().ToString();
var etag = new EntityTagHeaderValue(String.Concat("\"", hash, "\""), true);
if (Request.Headers.IfNoneMatch.Any(h => h.Equals(etag)))
{
return new HttpResponseMessage(HttpStatusCode.NotModified);
}
var response = this.Request.CreateResponse(HttpStatusCode.OK, obj);
response.Headers.ETag = etag;
return response;
Также было бы неплохо соблюдать заголовок If-Modified-Since. См. RFC 2616.
Ответ 4 · Stas Natalenko
Кажется, это то, что вы ищете (см. раздел "Поддержка ETags"):
http://blogs.msdn.com/b/webdev/archive/2014/03/13/начало-работы-с-asp-net-web-api-2-2-for-odata-v4-0.aspx
Если ваша модель хранится глубже в домене и вы не можете применить атрибут [ConcurrencyCheck], вы можете сделать это с помощью ODataModelBuilder:
ODataModelBuilder builder = new ODataConventionModelBuilder();
var myEntity = builder.EntitySet<MyEntity>("MyEntities");
myEntity.EntityType.Property(l => l.Version).ConcurrencyToken = true;
это заставит добавить свойство "@odata.etag" в тело ответа.
Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.
Похожие материалы
- Магическое число в заголовке GZip неверно. Убедитесь, что вы передаете поток GZip
- Jsonresult / запрос, возвращающий json, завернутый в XML
- Как я могу расширить поведение согласования контента в MVC4?
- Изменить имя внутренних объектов для сериализации ASP .NET MVC 4 WebAPI (XML/JSON)
- Дочернее приложение MVC4 должно переопределить сборку в родительском приложении web.config
- Аутентификация зависает после обновления Identityserver3