HttpWebRequest+HttpWebResponse经常会被使用在控制台应用程序中,比如检测页面是否正常或定期访问。随着需求的变化,我们可能需要将此功能迁移到windows服务中执行,windows服务不会被轻易的误关闭。
一、在控制台应用程序中使用HttpWebResponse:
HttpWebRequest request = WebRequest.Create(urlPath) as HttpWebRequest;
//如下三行效果一样,若全被注释了,那么将会看到401的异常信息。
request.UseDefaultCredentials = true; //request.Credentials = CredentialCache.DefaultNetworkCredentials;//request.Credentials = CredentialCache.DefaultCredentials;// Get the response.
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()){ if (response.StatusCode == HttpStatusCode.OK) { // Display the status. WriteLog(response.StatusDescription); // Get the stream containing content returned by the server. using (Stream dataStream = response.GetResponseStream()) { // Open the stream using a StreamReader for easy access. using (StreamReader reader = new StreamReader(dataStream)) { //Read the content. string responseFromServer = reader.ReadToEnd(); //Display the content. Console.WriteLine(responseFromServer); Console.WriteLine(DateTime.Now.ToString() + " Successed."); WriteLog("Successed"); } } } else { WriteLog("status code is not Ok it was" + response.StatusCode.ToString()); }}结论:以上代码可以正常运行,因为控制台应用程序是基于当前登录的用户身份去访问。
二、windows服务中使用HttpWebResponse
我们直接将以上代码迁移到windows服务中,理论上可以正常运行的。可实际情况出现了如下错误:
System.Net.WebException: 远程服务器返回错误: (401) 未经授权。
在 System.Net.HttpWebRequest.GetResponse()那么,我们如何解决呢?我们使用的是本地IIS的站点。先引用一个网友的一段话:
Windows Service application run under the LocalSystem account by default, whereas your console app runs under your user account, you may therefore be meeting permission problems (windows firewall?)
You should run the service under the administrator account to see if this resolves your issue.
试想一下,我们不难理解,windows服务程序是基于本地系统帐户运行的。
其实关键部分还是设置UseDefaultCredentials或者Credentials,代码中的三种方法是有效的。这三种方法的差别:
1. Credentials = CredentialCache.DefaultCredentials; 表示在发送请求会带上当前用户的身份验证凭据。
2. UseDefaultCredentials = true; 此方法在内部会调用前面的方法,因此与前面的方法是一样的。3. Credentials = CredentialCache.DefaultNetworkCredentials; 是在.NET 2.0中引用的新方法。解决方法一,修改凭证格式,指定用户名和密码:
request.UseDefaultCredentials = true;
修改为:
NetworkCredential credentials = new NetworkCredential("username", "pwd");
request.Credentials = credentials;