How to retrieve value of If-Modified-Since header?

Topics: Web Api
Oct 28, 2011 at 8:06 PM

I am having an issue retrieving the value of the If-Modified-Since header in my Web API service.

I have the following service operation:

[WebInvoke(Method = "GET", UriTemplate = "/{id}")]
public IQueryable<TheContract> ListSomething(String id)
{
    var since = String.Format("If-Modified-Since header (1): {0}", WebOperationContext.Current.IncomingRequest.IfModifiedSince);
}

Regardless what I put in the header, 'since' always equals "12/31/1969 7:00:00 PM".

What am I missing?

Oct 29, 2011 at 12:13 AM

You're mixing Web API and WCF REST approaches.  I'm actually surprised that WebOperationContext.Current actually returns a non-null value.

Try this,

[WebInvoke(Method = "GET", UriTemplate = "/{id}")]
public IQueryable<TheContract> ListSomething(String id, HttpRequestHeaders requestHeaders)
{
    var since = String.Format("If-Modified-Since header (1): {0}", requestHeaders.IfModifiedSince);
}
Oct 30, 2011 at 4:26 PM

When I add the HttpRequestHeaders argument to my service method I get the following error:

The service operation 'ListSystemSettings' will never receive a value for the input parameter 'headers' of type 'HttpRequestHeaders'. Ensure that a request HttpOperationHandler has an output parameter with a type assignable to 'HttpRequestHeaders'.

 

Coordinator
Oct 30, 2011 at 6:19 PM
Edited Oct 30, 2011 at 6:20 PM

Try using HttpRequestMessage as the param. Then access the headers collection off of the request.

Darrel, WebOperationContext.Current doesn't return an error, the error is if you try to access the properties on it ;-)

Oct 30, 2011 at 11:43 PM

Two follow-ups:

1. Should I be adding a second parameter of type HttpRequestMessage, or refactoring the existing parameter to be HttpRequestMessage<String>?

2. When I add a second parameter of type HttpRequestMessage (in other words, I implement Darrel's suggestion but with HttpRequestMessage), then check request.Headers.IfModifiedSince, I always get 'null' regardless of the format I use for the header value.

(I'm using the test client to generate the requests.)

 

Oct 31, 2011 at 2:34 AM

1) Either option should work.  I don't think there is a right/wrong way.  It's a preference issue.

 

2)  This worked for me....

 

	[WebInvoke(UriTemplate = "SendIfModifiedSinceHeader", Method = "GET")]
        public HttpResponseMessage SendIfModifiedSinceHeader(HttpRequestMessage requestMessage) {

            var response = new HttpResponseMessage(HttpStatusCode.OK); ;
            response.Content = new StringContent(requestMessage.Headers.IfModifiedSince.Value.ToString("yyyy-MM-dd hh:mmtt"));
            return response;

        }

 

	[Fact]
        public void ReadIfModifiedSinceHeader() {

            var httpClient = new HttpClient();
            httpClient.BaseAddress = new Uri(_HostUrl);
            var request = new HttpRequestMessage(HttpMethod.Get,new Uri("SendIfModifiedSinceHeader",UriKind.Relative));
            request.Headers.IfModifiedSince = new DateTimeOffset(DateTime.Parse("2010-10-01 09:00am +00"));

            var responseMessage = httpClient.Send(request);

            Assert.Equal(HttpStatusCode.OK, responseMessage.StatusCode);
            Assert.Equal("2010-10-01 09:00AM", responseMessage.Content.ReadAsString());
        }

Nov 1, 2011 at 12:31 PM

When I run your method exactly as written using the Test Client, I get a "Nullable object must have a value." error. This is because, as I ran into previously, 'requestMessage.Headers.IfModifiedSince' is null.

When I run your test code it works correctly.  Is this a formatting issue with the value that is passed in the header?  It doesn't seem to matter what value I send through the Test Client (or Fiddler), the header is always null.

 

 

Nov 1, 2011 at 1:22 PM

Yeah, it looks like the date format must comply to the syntax defined here http://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-17#section-8  My header looked like this:

If-Modified-Since: Fri, 01 Oct 2010 09:00:00 GMT

Nov 1, 2011 at 1:47 PM

Still must be something wrong with my configuration or code.  I copied your header exactly as-is from your post and used it in my request.  I still get a null value for the header. Is there anything else that could be interfering with the header when accessing from the Test Client or Fiddler?