使用HttpClient访问作为虚拟目录运行的web服务
本文关键字:运行 web 服务 虚拟 HttpClient 访问 使用 | 更新日期: 2023-09-27 18:07:36
我们有一个MVC web应用程序,它使用System.Net.HttpClient.PostAsJsonAsync在服务器端调用web服务。
当web服务在IIS中作为根站点运行时,这工作正常。但是当我们在IIS中将其配置为虚拟目录时,System.Net.HttpClient.PostAsJsonAsync会发送到错误的URL。
using (var client = new HttpClient())
{
var webServiceUrl = ConfigurationManager.AppSettings["WebServiceUrl"];
if (webServiceUrl == null)
throw new Exception("WebServiceUrl not set in web.config");
client.BaseAddress = new Uri(webServiceUrl);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response =
await client.PostAsJsonAsync("api/Authentication", loginModel);
if (response.IsSuccessStatusCode)
...
当我在调试器中跟踪时,我看到webServiceUrl被设置为一个域+虚拟目录(即http://mydomain.com/myvirtualdirectory)。
然后当我得到响应时,它有一个StatusCode 404, "Not Found"。事情是这样的——响应对象包含RequestMessage,而请求中的URL不包含虚拟目录。
我们从BaseAddress"http://mydomain.com/myvirtualdirectory"和RequestUri"api/Authentication"开始,我在RequestMessage中看到的是"http://mydomain.com/api/Authentication"。虚拟目录已被剥离。
问题是,为什么?
这里似乎很清楚:WebClient不知道虚拟目录。从客户机的角度来看,虚拟目录只是另一个文件夹。所以不用
await client.PostAsJsonAsync("api/Authentication", loginModel);
应该使用:
await client.PostAsJsonAsync("myvirtualdirectory/api/Authentication", loginModel);
您可能希望BaseUri
以斜杠结尾。
想象一下,你的浏览器在http://example.com/myvirtualdirectory
上,有一个链接到api
。它会去哪里?
To http://example.com/api
。
想象一下,有一个链接到api/Authentication
。它指向哪里?致http://example.com/api/Authentication
.
你知道为什么会这样了吧。您知道myvirtualdirectory
是一个目录,但它在机器上看起来不像。