【知识点】Uri对象的完整地址

匿名 (未验证) 提交于 2019-12-02 23:43:01

通过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对象具体实现。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!