From 959b3ceef4fb6a316c4d2fd3c4728f19fd4cd041 Mon Sep 17 00:00:00 2001 From: gdownes Date: Wed, 25 Feb 2015 11:44:48 +0000 Subject: [PATCH] Support for OData Caching - Added patch and merge to auto invalidate http methods. Added full controller name to cache key generator. Added default media type. --- .../AutoInvalidateCacheOutputAttribute.cs | 4 +++- .../CacheOutputAttribute.cs | 17 ++++++++++++----- .../DefaultCacheKeyGenerator.cs | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/WebApi.OutputCache.V2/AutoInvalidateCacheOutputAttribute.cs b/src/WebApi.OutputCache.V2/AutoInvalidateCacheOutputAttribute.cs index 39e1dfc..85dc530 100644 --- a/src/WebApi.OutputCache.V2/AutoInvalidateCacheOutputAttribute.cs +++ b/src/WebApi.OutputCache.V2/AutoInvalidateCacheOutputAttribute.cs @@ -20,7 +20,9 @@ public override void OnActionExecuted(HttpActionExecutedContext actionExecutedCo if (actionExecutedContext.Response != null && !actionExecutedContext.Response.IsSuccessStatusCode) return; if (actionExecutedContext.ActionContext.Request.Method != HttpMethod.Post && actionExecutedContext.ActionContext.Request.Method != HttpMethod.Put && - actionExecutedContext.ActionContext.Request.Method != HttpMethod.Delete) return; + actionExecutedContext.ActionContext.Request.Method != HttpMethod.Delete && + actionExecutedContext.ActionContext.Request.Method.Method.ToLower() != "patch" && + actionExecutedContext.ActionContext.Request.Method.Method.ToLower() != "merge") return; var controller = actionExecutedContext.ActionContext.ControllerContext.ControllerDescriptor; var actions = FindAllGetMethods(controller.ControllerType, TryMatchType ? actionExecutedContext.ActionContext.ActionDescriptor.GetParameters() : null); diff --git a/src/WebApi.OutputCache.V2/CacheOutputAttribute.cs b/src/WebApi.OutputCache.V2/CacheOutputAttribute.cs index f34f6b1..07d9f1d 100644 --- a/src/WebApi.OutputCache.V2/CacheOutputAttribute.cs +++ b/src/WebApi.OutputCache.V2/CacheOutputAttribute.cs @@ -103,10 +103,17 @@ protected virtual MediaTypeHeaderValue GetExpectedMediaType(HttpConfiguration co if (negotiator != null && returnType != typeof(HttpResponseMessage)) { var negotiatedResult = negotiator.Negotiate(returnType, actionContext.Request, config.Formatters); + if (negotiatedResult != null) + { responseMediaType = negotiatedResult.MediaType; if (string.IsNullOrWhiteSpace(responseMediaType.CharSet)) { responseMediaType.CharSet = Encoding.UTF8.HeaderName; + } + } + else + { + return DefaultMediaType; } } else @@ -145,7 +152,7 @@ private void OnActionExecuting(HttpActionContext actionContext) if (actionContext.Request.Headers.IfNoneMatch != null) { - var etag = _webApiCache.Get(cachekey + Constants.EtagKey) as string; + var etag = _webApiCache.Get(cachekey + Constants.EtagKey); if (etag != null) { if (actionContext.Request.Headers.IfNoneMatch.Any(x => x.Tag == etag)) @@ -159,16 +166,16 @@ private void OnActionExecuting(HttpActionContext actionContext) } } - var val = _webApiCache.Get(cachekey) as byte[]; + var val = _webApiCache.Get(cachekey); if (val == null) return; - var contenttype = _webApiCache.Get(cachekey + Constants.ContentTypeKey) as MediaTypeHeaderValue ?? new MediaTypeHeaderValue(cachekey.Split(new[] {':'},2)[1]); + var contenttype = _webApiCache.Get(cachekey + Constants.ContentTypeKey) ?? new MediaTypeHeaderValue(cachekey.Split(new[] { ':' }, 2)[1]); actionContext.Response = actionContext.Request.CreateResponse(); actionContext.Response.Content = new ByteArrayContent(val); actionContext.Response.Content.Headers.ContentType = contenttype; - var responseEtag = _webApiCache.Get(cachekey + Constants.EtagKey) as string; + var responseEtag = _webApiCache.Get(cachekey + Constants.EtagKey); if (responseEtag != null) SetEtag(actionContext.Response, responseEtag); var cacheTime = CacheTimeQuery.Execute(DateTime.Now); @@ -221,7 +228,7 @@ private async Task OnActionExecuted(HttpActionExecutedContext actionExecutedCont ApplyCacheHeaders(actionExecutedContext.ActionContext.Response, cacheTime); } - protected virtual void ApplyCacheHeaders(HttpResponseMessage response, CacheTime cacheTime) + private void ApplyCacheHeaders(HttpResponseMessage response, CacheTime cacheTime) { if (cacheTime.ClientTimeSpan > TimeSpan.Zero || MustRevalidate || Private) { diff --git a/src/WebApi.OutputCache.V2/DefaultCacheKeyGenerator.cs b/src/WebApi.OutputCache.V2/DefaultCacheKeyGenerator.cs index 6dd2828..cf02a29 100644 --- a/src/WebApi.OutputCache.V2/DefaultCacheKeyGenerator.cs +++ b/src/WebApi.OutputCache.V2/DefaultCacheKeyGenerator.cs @@ -13,7 +13,7 @@ public class DefaultCacheKeyGenerator : ICacheKeyGenerator { public virtual string MakeCacheKey(HttpActionContext context, MediaTypeHeaderValue mediaType, bool excludeQueryString = false) { - var controller = context.ControllerContext.ControllerDescriptor.ControllerName; + var controller = context.ControllerContext.ControllerDescriptor.ControllerType.FullName; var action = context.ActionDescriptor.ActionName; var key = context.Request.GetConfiguration().CacheOutputConfiguration().MakeBaseCachekey(controller, action); var actionParameters = context.ActionArguments.Where(x => x.Value != null).Select(x => x.Key + "=" + GetValue(x.Value));