# url拼接 拼接`http://www.example.com/endpoint` ``` //通过string的扩展方法 var url = "http://www.example.com" .AppendPathSegment("endpoint"); var url = new Url("http://www.example.com").AppendPathSegment(); ``` 查询字符串拼接`http://www.example.com/endpoint/api_key=sth&max_results=sth&q=sth` ``` var url = "http://www.example.com" .AppendPathSegment("endpoint") .SetQueryParams(new { api_key = sth, max_results = sth, q = sth }); ``` `SetQueryParams`一般会覆盖前面的设置。但是,如果为相同的query变量设置不同的值,可以传入数组或集合。例如:`http://www.example.com/endpoint/x=1&x=2&x=3` ``` var url = "http://www.example.com" .SetQueryParams("x", new[]{1, 2, 3}); ``` 关于编码,`flurl`会对查询字符串进行编码,对路径部分的保留字`/`、`%`不会编码,路径部分的空格会编码,路径部分的`?`会编码。 `SetQueryParam`还有一个禁用query编码的重载方法。 ``` var url = "http://www.example.com" .AppendPathSegment("endpoint") .SetQueryParam("x", "don%27t%20touch%20m", true) ``` 默认会把空格编码成`%20`,但有时候希望把空格编码成`+`。 ``` var url = "http://www.example.com" .AppendPathSegment("endpoint") .SetQueryParam("x","hi") .ToString(true); ``` 取出url地址中的不同部分,例如`http://www.example.com/with/path?x=1&y=3#foo` ``` var url = new Url("http://www.example.com/with/path?x=1&y=3#foo"); var path = url.Path;//http://www.example.com/with/path var query= url.Query;//x=1&y=3 var paramVal = url.QueryParams["y"];//3 var fragment = url.Fragment; //foo ``` 多个url部分拼接。 ``` //http://www.foo.com/too/many/few?x=1&y=2 var url = Url.Combine("http://foo.com/","/too/","/many/","few?","x=1","y=2"); ``` 其它API ``` string Path{get;set;} string Query Fragment{get;set;} QueryParamCollectio QueryParams{get;} Url AppendPathSegment(); Url SetQueryParam(); Url RemoveQueryParams(); Url SetFragment(); Url RemoveFragment(); Url ResetToRoot(); bool IsValid(); string ToString(bool encodeSpaceAsPlus); string Combine(params string[] parts); QueryParamCollection ParseQueryParams(string query); string GetRoot(string url); string DecodeQueryParamValue(string value); string EncodeQueryParamValue(object value, bool encodeSpaceAsPlus); string EncodeILlegalCharacter(strint urlPart); ``` # Fluent HTTP 需要引用两个插件 ``` using Flurl; using Flurl.Http; ``` 发送一般请求: ``` var getResp = await "".GetAsync(); ``` 发动GET请求: ``` var headResp = await "".HeadAsync(); ``` 获取强类型 ``` T poco = await "".GetJsonAsync(); dynamic d = await "".GetJsonAsync(); var list = await "".GetJsonListAsync(); ``` 获取string ``` string text = await "".GetStringAsync(); ``` 获取bytes ``` byte[] bytes = await "".GetBytesAsync(); ``` 获取流 ``` Stream stream = await "".GetStreamAsync(); ``` 下载文件 ``` var path = await "http://files.foo.com/image.jpg" .DownloadFileAsync("c:\\downloads", filename); ``` 发送json数据 ``` await "".PostJsonAsync(new {a=1,b=2}); ``` 设置headers ``` await url.WithHeader("Accept","text/plain").GetJsonAsync(); await url.WithHeaders(new {Accept="text/plain", User_Agent=""}).GetJosnAsync(); ``` 设置验证 ``` 一般验证:await url.WithBasicAuth("","").GetJsonAsync(); OAUth验证:await url.WithOAuthBearerToken("mytoken").GetJsonAsync(); ``` 设置过期时间 ``` await url.WithTimeout(10).DownloadFileAsync(); //10秒 await url.WithTimeout(TimeSpan.FromMinutes(2)).DownloadFileAsync(); ``` 设置cookie ``` await url.WithCookie("name","value", expDate).HeadAsync(); await url.WithCookies(new {c1=1, c2=2}, expDate).HeadAsync(); ``` 取消请求 ``` var cts = new CancellationTokenSource(); var task = url.GetAsync(cts.Token); cts.Cancel(); ``` 发送表单数据 ``` await "".PostUrlEncodeAsync(new {user = "", pass=""}); ``` 发送表单数据,并且处理返回结果 ``` T poco = await url.PostJsonAsync(data).ReceiveJson(); dynamic d = await url.PostUrlEncodeAsync(data).ReceiveJson(); string s = await url.PostUrlEncodeAsync(data).ReceiveString(); ``` 使用原生的`HttpClient` ``` await url.PostAsync(httpContent); await url.SendJsonAsync(HttpMethod.Options, poco); await url.SendAsync(HttpMethod.Trace, httpContent, cancellationToken,HttpCompletionOption.ResponseHeaderRead); ``` # 异常处理 一般处理,适用于XXX异常 ``` try{ await url.PostJsonAsync(poco); } catch(FlurlHttpTimeoutException){ LogError("timeout"); } catch(FlurHttpException ex){ LogError(ex.Message); } ``` 使用扩展方法处理异常,适用于XXX异常 ``` catch(FlurlHttpException ex){ TError e = ex.GetResponseJson(); dynamic d = ex.GetResponseJson(); } ``` 允许除了2XX的异常 ``` url.AllowHttpStatus(HttpStatusCode.NotFound, HttpStatusCode.Conflict).GetAsync(); url.AllowHttpStatus("400-404,6xx").GetAsync(); url.AllowAnyHttpStatus().GetAsync(); ```