我正在使用WebClient
检索网站。我决定设置If-Modified-Since
,因为如果网站没有更改,我不想再得到它:
var c = new WebClient();
c.Headers[HttpRequestHeader.IfModifiedSince] = Last_refreshed.ToUniversalTime().ToString("r");
其中Last_refreshed
是一个变量,我在其中存储上次访问网站的时间。
但当我运行此程序时,我会得到一个WebException
,其文本为:
The 'If-Modified-Since' header must be modified using the appropriate property or method.
Parameter name: name
原来API文档提到了这一点:
此外,当使用
WebClient
对象时,一些其他标头也会受到限制。这些受限标头包括但不限于以下内容:
- 接受
- 连接
- 内容长度
- Expect(当值设置为"100 continue"时)
- 如果修改自
- 范围
- 传输编码
HttpWebRequest
类具有用于设置上述某些标头的属性。如果应用程序设置这些标头很重要,那么应该使用HttpWebRequest
类而不是WebRequest
类。
那么,这是否意味着无法从WebClient
设置它们?为什么不呢?在正常的HTTP GET
中指定If-Modified-Since
有什么问题?
我知道我可以只使用HttpWebRequest
,但我不想这样做,因为这太工作量了(必须做大量的选角,不能只将内容作为字符串)。
此外,我知道在使用System.Net.WebRequest时无法设置某些HTTP标头是相关的,但它实际上并不能回答我的问题。
尽管它可能很难处理,但我选择了WebClient
的子类,以便以模仿WebClient
通常工作方式的方式添加功能(每次使用后头被消耗/重置):
public class ApiWebClient : WebClient {
public DateTime? IfModifiedSince { get; set; }
protected override WebRequest GetWebRequest(Uri address) {
var webRequest = base.GetWebRequest(address);
var httpWebRequest = webRequest as HttpWebRequest;
if (httpWebRequest != null) {
if (IfModifiedSince != null) {
httpWebRequest.IfModifiedSince = IfModifiedSince.Value;
IfModifiedSince = null;
}
// Handle other headers or properties here
}
return webRequest;
}
}
这样做的优点是不必为WebClient提供的标准操作编写样板,同时还提供了使用WebRequest的一些灵活性。