
We develop an application for several platforms, we create the entire platform-independent part using PCL, trying to achieve the maximum level of component reuse. For communications with the server, the HttpWebRequest class is used which implements all the necessary functionality from the transport layer.
Recently, the protocol has been optimized, it became possible to reduce the amount of transmitted data indicating the horizon of relevance. This optimization has been implemented using the IfModifiedSince HTTP header processing, however, the HttpWebRequest object in PCL does not have the IfModifiedSince property. This did not seem to be a problem; the header was added directly to the collection of request headers.
request.Headers[HttpRequestHeader.IfModifiedSince] = timeStamp.ToString();
Having tested the solution on the WindowsPhone application, I was convinced of its efficiency, but all unit tests of the transport level gave errors.
After examining the problem, I discovered that the WebHeaderCollection implementation for the Windows platform does not allow this header to be set directly and requires developers to use the HttpWebRequest.IfModifiedSince property that is not available in PCL assemblies.
')
To solve this, I created an extension method for the HttpWebRequest class that implements the following operation logic:
At the first call to the method, we try to add a header to the collection of request headers, if this fails, using reflection, we search the If object for the request object in the IfModifiedSince field, create and cache a delegate to set the property value.
On subsequent calls to the method, use the cached delegate to set the value of the IfModifiedSince header.
namespace System.Net { public static class NetExtensions { private static Action<HttpWebRequest, DateTime> _setIfMofifiedSince; public static void SetIfModifiedSince(this HttpWebRequest request, DateTime value) { Guard.NotNull(request); if (_setIfMofifiedSince != null) { _setIfMofifiedSince(request, value); return; } try { request.Headers[HttpRequestHeader.IfModifiedSince] = value.ToString(); return; }
Using this extension method, the code remains easy to read and understand.
request.SetIfModifiedSince(timeStamp);