通过HttpClient发送请求时,可以先设置BaseAddress,之后的请求直接传入相对地址即可:
1 using(var httpClient = new HttpClinet()) 2 { 3 httpClient.BaseAddress = new Uri("http://localhost:8082"); 4 await httpClient.GetAsync("Users"); // GET http://localhost:8082/Users 5 await httpClient.PutAsync("User/123", xx); // PUT http://localhost:8082/User/123 6 }
但是这里呢有个坑,就是传入的Uri是否以“/”结尾或开头,会使得最终请求的地址发生变化。
做个测试:
1 var baseUri = new Uri("http://localhost:8082/api"); 2 var relativeUri = new Uri("Users", UriKind.Relative); 3 var requestUri = new Uri(baseUri, relativeUri); 4 Console.WriteLine(requestUri); // http://localhost:8082/Users 5 6 var baseUri = new Uri("http://localhost:8082/api/"); 7 var relativeUri = new Uri("Users", UriKind.Relative); 8 var requestUri= new Uri(baseUri , relativeUri); 9 Console.WriteLine(requestUri); // http://localhost:8082/api/Users 10 11 var baseUri = new Uri("http://localhost:8082/api"); 12 var relativeUri = new Uri("/Users", UriKind.Relative); 13 var requestUri= new Uri(baseUri, relativeUri); 14 Console.WriteLine(requestUri); // http://localhost:8082/Users 15 16 var baseUri = new Uri("http://localhost:8082/api/"); 17 var relativeUri = new Uri("/Users", UriKind.Relative); 18 var requestUri= new Uri(baseUri, relativeUri); 19 Console.WriteLine(requestUri); // http://localhost:8082/Users
可以看出,只有baseUri以“/”结尾,且relativeUri不以“/”开头,才会得到完整的Uri,其它的都会缺失“api”这部分。
查找官方文档,可以找到相关说明(Uri构造函数):
1、如果relativeUri是绝对地址,那么最终地址采用relativeUri
2、如果baseUri包含相对部分,那么只会保留以“/”结尾的相对部分
3、如果relativeUri以“/”开头,那么会替换掉baseUri中所有的相对部分
按上述条件接着测试:
1 var baseUri = new Uri("http://localhost:8082/api"); 2 var relativeUri = new Uri("http://localhost:8082/api2"); 3 var requestUri = new Uri(baseUri, relativeUri); 4 Console.WriteLine(requestUri); // http://localhost:8082/api2 5 6 var baseUri = new Uri("http://localhost:8082/api/test"); 7 var relativeUri = new Uri("Users", UriKind.Relative); 8 var requestUri = new Uri(baseUri, relativeUri); 9 Console.WriteLine(requestUri); // http://localhost:8082/api/Users 10 11 var baseUri = new Uri("http://localhost:8082/api/test/"); 12 var relativeUri = new Uri("Users", UriKind.Relative); 13 var requestUri = new Uri(baseUri, relativeUri); 14 Console.WriteLine(requestUri); // http://localhost:8082/api/test/Users 15 16 var baseUri = new Uri("http://localhost:8082/api/test/"); 17 var relativeUri = new Uri("/Users", UriKind.Relative); 18 var requestUri = new Uri(baseUri, relativeUri); 19 Console.WriteLine(requestUri); // http://localhost:8082/Users 20 21 var baseUri = new Uri("http://localhost:8082/api/test/"); 22 var relativeUri = new Uri("/User/123/", UriKind.Relative); 23 var requestUri = new Uri(baseUri, relativeUri); 24 Console.WriteLine(requestUri); // http://localhost:8082/User/123/
结果很清晰,最终Uri优先取决relativeUri,其次取决baseUri。
不过,如果仅有baseUri或relativeUri,那还会按“/”来分割吗?继续测试:
1 var baseUri = new Uri("http://localhost:8082/api/test/"); 2 var relativeUri = new Uri("http://localhost:8082/api2/test"); 3 var requestUri = new Uri(baseUri, relativeUri); 4 Console.WriteLine(requestUri); // http://localhost:8082/api2/test 5 6 var baseUri = new Uri("http://localhost:8082/api/test"); 7 var relativeUri = new Uri("/", UriKind.Relative); 8 var requestUri = new Uri(baseUri, relativeUri); 9 Console.WriteLine(requestUri); // http://localhost:8082/ 10 11 var baseUri = new Uri("http://localhost:8082/api/test"); 12 var relativeUri = new Uri("", UriKind.Relative); 13 var requestUri = new Uri(baseUri, relativeUri); 14 Console.WriteLine(requestUri); // http://localhost:8082/api2/test 15 16 var relativeUri = new Uri("/api/Users", UriKind.Relative); 17 Console.WriteLine(relativeUri); // /api/Users
所以根据测试结果可以追加2条规则:
1、如果relativeUri是绝对地址,那么完全采用relativeUri,无论是否以“/”结尾
2、如果仅有baseUri或relativeUri,那么不做任何处理
另外,有兴趣的可以反编译System.dll看看Uri对象具体实现。