I'm trying to return a status code of 304 not modified for a GET method in a web api controller.
The only way I succeeded was something like this:
public class TryController : ApiController
{
public User GetUser(int userId, DateTime lastModifiedAtClient)
{
var user = new DataEntities().Users.First(p => p.Id == userId);
if (user.LastModified <= lastModifiedAtClient)
{
throw new HttpResponseException(HttpStatusCode.NotModified);
}
return user;
}
}
The problem here is that it's not an exception, It's just not modified so the client cache is OK. I also want the return type to be a User (as all the web api examples shows with GET) not return HttpResponseMessage or something like this.
You can also do the following if you want to preserve the action signature as returning User:
If you want to return something other than
200
then you throw anHttpResponseException
in your action and pass in theHttpResponseMessage
you want to send to the client.I did not know the answer so asked the ASP.NET team here.
So the trick is to change the signature to
HttpResponseMessage
and useRequest.CreateResponse
.Change the GetXxx API method to return HttpResponseMessage and then return a typed version for the full response and the untyped version for the NotModified response.
*The ClientHasStale data is my extension for checking ETag and IfModifiedSince headers.
The MVC framework should still serialize and return your object.
NOTE
I think the generic version is being removed in some future version of the Web API.
Another option:
I don't like having to change my signature to use the HttpCreateResponse type, so I came up with a little bit of an extended solution to hide that.
You can then add a method to your ApiController (or better your base controller) like this:
Then you can return it just like any of the built in methods: