まずIf-Modified-Since
、リソースの最終変更時刻に関する条件ETag
付き GET と、リソースの識別子に関する条件付き GET についてですので、2 つの概念を混在させる場合は注意してください。
WCF サービスで If-Modified-Since のサポートを実装する正しい方法は、オブジェクトで値CheckConditionalRetrieve
を渡すことです。これについては、以下のコードを参照してください。IMS ヘッダーの値が に渡す日付より前の場合、メソッドはその時点で終了し、304 (Not Modified) 応答を返します。そうでなければ、それはただ続くでしょう。以下のコードはそれを示しています。DateTime
WebOperationContext.Current.IncomingRequest
CheckConditionalRetrieve
別の問題: 使用している日付形式 (ISO 8601) でも機能しますが、仕様に基づいて正しくありません ( http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.htmlのセクション 14.25 、およびhttp://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1のセクション 3.3.1 を参照)、将来の問題を防ぐために有効な形式の使用を検討する必要があります。
http://blogs.msdn.com/b/endpoint/archive/2010/02/25/conditional-get-and-etag-support-in-wcf-webhttpで、WCF での条件付き GET サポートに関する適切な投稿を見つけることができます。-services.aspx .
public class StackOverflow_7919718
{
[ServiceContract]
public class Service
{
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public string GetData()
{
Console.WriteLine("If-Modified-Since header (1): {0}", WebOperationContext.Current.IncomingRequest.IfModifiedSince);
WebOperationContext.Current.IncomingRequest.CheckConditionalRetrieve(DateTime.UtcNow);
return "Data";
}
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
WebServiceHost host = new WebServiceHost(typeof(Service), new Uri(baseAddress));
host.Open();
Console.WriteLine("Host opened");
Console.WriteLine("Not sending If-Modified-Since header (should return 200):");
Util.SendRequest(baseAddress + "/GetData", "GET", null, null);
Console.WriteLine("Sending data in the past, ISO 8601 format (should return 200):");
Util.SendRequest(baseAddress + "/GetData", "GET", null, null,
new Dictionary<string, string> { { "If-Modified-Since", "2011-10-25T13:09:39.6242263-04:00" } });
Console.WriteLine("Sending data in the future, ISO 8601 format (should return 304):");
Util.SendRequest(baseAddress + "/GetData", "GET", null, null,
new Dictionary<string, string> { { "If-Modified-Since", "2021-10-25T13:09:39.6242263-04:00" } });
Console.WriteLine("Sending data in the past, RFC 1123 format (should return 200):");
Util.SendRequest(baseAddress + "/GetData", "GET", null, null,
new Dictionary<string, string> { { "If-Modified-Since", "Wed, 26 Oct 2011 01:00:00 GMT" } });
Console.WriteLine("Sending data in the future, RFC 1123 format (should return 304):");
Util.SendRequest(baseAddress + "/GetData", "GET", null, null,
new Dictionary<string, string> { { "If-Modified-Since", "Mon, 27 Oct 2031 10:00:00 GMT" } });
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}
public static class Util
{
public static string SendRequest(string uri, string method, string contentType, string body)
{
return SendRequest(uri, method, contentType, body, null);
}
public static string SendRequest(string uri, string method, string contentType, string body, Dictionary<string, string> headers)
{
string responseBody = null;
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uri);
req.Method = method;
if (headers != null)
{
foreach (string headerName in headers.Keys)
{
switch (headerName)
{
case "If-Modified-Since":
req.IfModifiedSince = DateTime.Parse(headers[headerName]);
break;
default:
req.Headers[headerName] = headers[headerName];
break;
}
}
}
if (!String.IsNullOrEmpty(contentType))
{
req.ContentType = contentType;
}
if (body != null)
{
byte[] bodyBytes = Encoding.UTF8.GetBytes(body);
req.GetRequestStream().Write(bodyBytes, 0, bodyBytes.Length);
req.GetRequestStream().Close();
}
HttpWebResponse resp;
try
{
resp = (HttpWebResponse)req.GetResponse();
}
catch (WebException e)
{
resp = (HttpWebResponse)e.Response;
}
if (resp == null)
{
responseBody = null;
Console.WriteLine("Response is null");
}
else
{
Console.WriteLine("HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);
foreach (string headerName in resp.Headers.AllKeys)
{
Console.WriteLine("{0}: {1}", headerName, resp.Headers[headerName]);
}
Console.WriteLine();
Stream respStream = resp.GetResponseStream();
if (respStream != null)
{
responseBody = new StreamReader(respStream).ReadToEnd();
Console.WriteLine(responseBody);
}
else
{
Console.WriteLine("HttpWebResponse.GetResponseStream returned null");
}
}
Console.WriteLine();
Console.WriteLine(" *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* ");
Console.WriteLine();
return responseBody;
}
}