Reputation: 18065
I am just starting with web-api 2 and stumbled upon : how to set caching settings. I have custom caching-message-handler
like below (simplified for SO post)
public class CachingMessageHandler : DelegatingHandler
{
private void SetCachingPolicy(HttpResponseMessage response)
{
response.Headers.CacheControl = new CacheControlHeaderValue
{
MaxAge = TimeSpan.FromSeconds(100),
};
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
return base
.SendAsync(request, cancellationToken)
.ContinueWith(task =>
{
var response = task.Result;
if (request.Method == HttpMethod.Get) SetCachingPolicy(response);
return response;
}, cancellationToken);
}
}
and I have various hello-world HttpGet api's
[HttpGet]
public HttpResponseMessage Get1()
{
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, "value");
response.Content = new StringContent("Hello World 1", Encoding.Unicode);
return response;
}
[HttpGet]
public HttpResponseMessage Get2()
{
return Request.CreateResponse(HttpStatusCode.OK, "Hello World 2");
}
[HttpGet]
public HttpResponseMessage Get2_1()
{
var response = Request.CreateResponse(HttpStatusCode.OK, "Hello World 2");
response.Headers.CacheControl = null;
return response;
}
[HttpGet]
public OkNegotiatedContentResult<string> Get3()
{
return Ok("Hello World 3");
}
[HttpGet]
public string Get4()
{
return "Hello World 4";
}
but the caching-message-handler
is applied only for Get1
api, for all other Get2/3/4
api's, it seems some default caching setting is used. Below is the response in postman
Can someone please explain this behavior!!! why is caching only applied for Content-Type : text/plain
and not for application/json
Upvotes: 2
Views: 1127
Reputation: 3050
I use angular and WebAPI with owin to build app too, and I have a custom cache filter too, but I use System.Web.Http.Filters.ActionFilterAttribute
instead of DelegatingHandler
, and it works for all response types, here is my custom cache filter code:
public class NoCacheFilter : System.Web.Http.Filters.ActionFilterAttribute {
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) {
if (actionExecutedContext.Request.Method == System.Net.Http.HttpMethod.Get && actionExecutedContext.Response != null) {
actionExecutedContext.Response.Headers.CacheControl = new CacheControlHeaderValue {
NoCache = true, NoStore = true, MustRevalidate = true,
//MaxAge = TimeSpan.FromSeconds(100)
};
actionExecutedContext.Response.Headers.Pragma.Add(new NameValueHeaderValue("no-cache"));
if (actionExecutedContext.Response.Content != null) {
actionExecutedContext.Response.Content.Headers.Expires = DateTimeOffset.UtcNow;
}
}
base.OnActionExecuted(actionExecutedContext);
}
}
I register the filter in the Configure
method like this:
var config = new HttpConfiguration();
config.Filters.Add(new NoCacheFilter());
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
app.UseWebApi(config);
I think maybe you should try to use ActionFilterAttribute
.
Upvotes: 2
Reputation: 27043
You need to add Access-Control-Expose-Headers
header at the backend. CORS returns certain response headers, so you need to tell it to return any other custom headers.
Access-Control-Expose-Headers: your-custom-cache-header-1, your-custom-cache-header-2, any-other-headers
Update
Since postman returns the same results, so it is not angular-related issue. It all resides on the server logic. Try to debug the lifecycle of text/plain
and application/json
requests. That might give you an idea why certain headers are not being set for application/json
requests.
Upvotes: 1
Reputation: 238
Ideally you should disable caching from server side. But since you tagged angularjs
& you want to disable caching globally - you can do it like below
app.config(['$httpProvider', function($httpProvider) {
if (!$httpProvider.defaults.headers.get) $httpProvider.defaults.headers.get = {};
$httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache';
$httpProvider.defaults.headers.get['Pragma'] = 'no-cache';
}]);
Upvotes: 0