Skip to content

Commit 50abde7

Browse files
authored
Merge pull request filipw#220 from petermorlion/feature/mediatype
Allow bypassing content negotiation process
2 parents 37bc932 + 58fbd7d commit 50abde7

File tree

4 files changed

+46
-2
lines changed

4 files changed

+46
-2
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,18 @@ So you either should use unique method names inside a single controller, or (if
125125
return Teams;
126126
}
127127

128+
If you want to bypass the content negotiation process, you can do so by using the `MediaType` property:
129+
130+
[CacheOutput(ClientTimeSpan = 50, ServerTimeSpan = 50, MediaType = "image/jpeg")]
131+
public HttpResponseMessage Get(int id)
132+
{
133+
var response = new HttpResponseMessage(HttpStatusCode.OK);
134+
response.Content = GetImage(id); // e.g. StreamContent, ByteArrayContent,...
135+
response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
136+
return response;
137+
}
138+
139+
This will always return a response with `image/jpeg` as value for the `Content-Type` header.
128140

129141
Ignoring caching
130142
--------------------

src/WebApi.OutputCache.V2/CacheOutputAttribute.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public class CacheOutputAttribute : ActionFilterAttribute
4949
/// </summary>
5050
public int ClientTimeSpan { get; set; }
5151

52-
52+
5353
private int? _sharedTimeSpan = null;
5454

5555
/// <summary>
@@ -80,7 +80,12 @@ public int SharedTimeSpan
8080
/// Class used to generate caching keys
8181
/// </summary>
8282
public Type CacheKeyGenerator { get; set; }
83-
83+
84+
/// <summary>
85+
/// If set to something else than an empty string, this value will always be used for the Content-Type header, regardless of content negotiation.
86+
/// </summary>
87+
public string MediaType { get; set; }
88+
8489
// cache repository
8590
private IApiOutputCache _webApiCache;
8691

@@ -121,6 +126,11 @@ protected void ResetCacheTimeQuery()
121126

122127
protected virtual MediaTypeHeaderValue GetExpectedMediaType(HttpConfiguration config, HttpActionContext actionContext)
123128
{
129+
if (!string.IsNullOrEmpty(MediaType))
130+
{
131+
return new MediaTypeHeaderValue(MediaType);
132+
}
133+
124134
MediaTypeHeaderValue responseMediaType = null;
125135

126136
var negotiator = config.Services.GetService(typeof(IContentNegotiator)) as IContentNegotiator;

test/WebApi.OutputCache.V2.Tests/ServerSideTests.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,19 @@ public void will_not_cache_if_cacheouput_present_on_controller_but_action_has_ig
338338
// _cache.Verify(s => s.Add(It.Is<string>(x => x == "custom_key:response-ct"), It.IsAny<object>(), It.Is<DateTimeOffset>(x => x <= DateTime.Now.AddSeconds(100)), It.Is<string>(x => x == "cachekey-get_custom_key")), Times.Once());
339339
//}
340340

341+
[Test]
342+
public void override_mediatype()
343+
{
344+
var client = new HttpClient(_server);
345+
var req = new HttpRequestMessage(HttpMethod.Get, _url + "Get_c50_s50_image");
346+
var result = client.SendAsync(req).Result;
347+
348+
_cache.Verify(s => s.Contains(It.Is<string>(x => x == "webapi.outputcache.v2.tests.testcontrollers.samplecontroller-get_c50_s50_image:image/jpeg")), Times.Exactly(2));
349+
_cache.Verify(s => s.Add(It.Is<string>(x => x == "webapi.outputcache.v2.tests.testcontrollers.samplecontroller-get_c50_s50_image"), It.IsAny<object>(), It.Is<DateTimeOffset>(x => x <= DateTime.Now.AddSeconds(50)), null), Times.Once());
350+
_cache.Verify(s => s.Add(It.Is<string>(x => x == "webapi.outputcache.v2.tests.testcontrollers.samplecontroller-get_c50_s50_image:image/jpeg"), It.IsAny<object>(), It.Is<DateTimeOffset>(x => x <= DateTime.Now.AddSeconds(50)), It.Is<string>(x => x == "webapi.outputcache.v2.tests.testcontrollers.samplecontroller-get_c50_s50_image")), Times.Once());
351+
Assert.That(result.Content.Headers.ContentType, Is.EqualTo(new MediaTypeHeaderValue("image/jpeg")));
352+
}
353+
341354
[TearDown]
342355
public void fixture_dispose()
343356
{

test/WebApi.OutputCache.V2.Tests/TestControllers/SampleController.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Net;
22
using System.Net.Http;
3+
using System.Net.Http.Headers;
34
using System.Web.Http;
45
using WebApi.OutputCache.V2.TimeAttributes;
56

@@ -134,6 +135,14 @@ public HttpResponseMessage Get_request_noContent()
134135
return Request.CreateResponse(HttpStatusCode.Accepted);
135136
}
136137

138+
[CacheOutput(ClientTimeSpan = 50, ServerTimeSpan = 50, MediaType = "image/jpeg")]
139+
public HttpResponseMessage Get_c50_s50_image()
140+
{
141+
var response = new HttpResponseMessage(HttpStatusCode.OK) {Content = new ByteArrayContent(new byte[0])};
142+
response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
143+
return response;
144+
}
145+
137146
[InvalidateCacheOutput("Get_c100_s100")]
138147
public void Post()
139148
{

0 commit comments

Comments
 (0)