xamarin android中網絡請求的架構非常多,在項目中使用的是第三方的一個網絡請求架構restsharp,應該是github上.net網絡請求最多star的架構,沒有之一。這裡就簡單彙總了其他的一些網絡請求的例子,主要還是分為android和.net兩種平台。.net 中可以使用HttpWebRequest、HttpClient、RestSharp第三框的一些架構,android的有HttpURLConnectin、HttpClient、OkHttp、Retrofit、Volley
下面就用.net中的httpwebrequest、httpclient、restsharp和android中的httpURLConnection、okhttp實作一個get方式擷取圖檔、post方式送出表單,适合新手入門看看總結一下。
效果圖如下:
1.HttpWebRquest、HttpWebResponse
命名空間: System.Net;程式集: System(位于 System.dll)
1 public class HttpWebRequestUtil
2 {
3 //發送get請求擷取bytes
4 public static async System.Threading.Tasks.Task<byte[]> GetBytes(string path)
5 {
6 try
7 {
8 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(path);
9 request.Method = "get";
10 request.Timeout = 500;
11 //request.Proxy設定代理
12 //path 中可添加querystring參數
13 //request.UserAgent 請求的代理
14 HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
15 if (response.StatusCode == HttpStatusCode.OK)
16 {
17 Stream responseStream = response.GetResponseStream();
18 //将流轉成位元組
19 byte[] bytes = StreamUtil.StreamToBytes(responseStream);
20 return bytes;
21 }
22 else
23 return null;
24 }
25 catch (Exception ex)
26 {
27 return null;
28 }
29 }
30
31 public static async System.Threading.Tasks.Task<bool> PostForm(string path, string name, string pwd)
32 {
33 try
34 {
35 string formData = "name=" + name +"&pwd=" +pwd ;
36 byte[] bytes = Encoding.UTF8.GetBytes(formData);
37 StringBuilder strBuilder = new StringBuilder();
38 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(path);
39 request.Method = "get";
40 request.Timeout = 500;
41 request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
42 request.ContentLength = bytes.Length;
43 request.Method = "Post";
44 Stream requestStream = request.GetRequestStream();
45 requestStream.Write(bytes, 0, bytes.Length);
46 requestStream.Close();
47
48 HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
49 if (response.StatusCode == HttpStatusCode.OK)
50 {
51 StreamReader streamReader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
52 string content = JsonConvert.DeserializeObject<string>(streamReader.ReadToEnd());
53 streamReader.Close();
54 if (content == "success")
55 {
56 return true;
57 }
58 else
59 return false;
60 }
61 return false;
62 }
63 catch (Exception ex)
64 {
65 return false;
66 }
67 }
68 }
2.RestSharp .net常用的http網絡請求庫
當然重點還是說一下這個的。restsharp在github上的star應該是.net網絡請求庫最多的,(和第二名的差距比較大)。可以在nuget上直接添加引用restsharp。
github位址:
https://github.com/restsharp/RestSharprestSharp官網:
http://restsharp.org/stackoverflow上restsharp的相關問題彙總:
https://stackoverflow.com/questions/tagged/RestSharprestsharp有一下這麼幾個重要的有點:
- 輕量級的、基于HttpWebRequest的封裝(不依賴任何第三方元件、支援.net 任何平台上)
- 支援異步操作、支援http的get、post、put、delete等操作
- 使用簡單、易調試、request和response的類型齊全
- 功能齊全,支援oAuth 1, oAuth 2, Basic等授權驗證、可上傳檔案
- 自定義序列化和反序列化、自動檢測傳回的内容類型
1 public class RestSharpUtil
2 {
3 internal static RestClient Instance(string url)
4 {
5 var restClient = new RestClient(url)
6 {
7 Timeout = 5000,
8 ReadWriteTimeout = 5000
9 };
10 return restClient;
11 }
12 public static async System.Threading.Tasks.Task<bool> Post(string url, User user)
13 {
14 RestClient restClient = Instance(url);
15 RestRequest request = new RestRequest();
16 //request.AddQueryParameter("id","") 添加url的參數(AddUrlSegment)
17 //request.AddHeader("Authorization","token");添加請求頭參數
18 // request.AddHeader("content-type", "application/x-www-form-urlencoded; charset=UTF-8");
19 request.AddJsonBody(user);
20 //request.AddParameter("application/x-www-form-urlencoded; charset=UTF-8", user, ParameterType.RequestBody);
21 var response = await restClient.ExecutePostTaskAsync(request);
22 //var response = await restClient.ExecutePostTaskAsync<string>(request); 自動序列化
23 if (response.StatusCode == System.Net.HttpStatusCode.OK)
24 {
25 var result = JsonConvert.DeserializeObject<string>(response.Content);
26 if (result == "success")
27 {
28 return true;
29 }
30 return false;
31 }
32 else
33 {
34 return false;
35 }
36 }
37 public static async System.Threading.Tasks.Task<byte[]> Get(string url)
38 {
39 RestClient restClient = Instance(url);
40 RestRequest request = new RestRequest();
41 var response = await restClient.ExecuteGetTaskAsync(request);
42 if (response.StatusCode == System.Net.HttpStatusCode.OK)
43 {
44 var bytes = response.RawBytes;
45 return bytes;
46 }
47 return null;
48 }
49 }
post請求和get請求在編碼類型不同,get:僅一種 application/x-www-form-urlencoded,post:application/x-www-form-urlencoded 或 multipart/form-data……等多種編碼方式。
restsharp在發送post請求方式時必須設定header的content-type解碼方式。
request.AddJsonBody(user);等同于:
request.AddParameter(“application/x-www-form-urlencoded; charset=UTF-8”, user, ParameterType.RequestBody);等同于:
request.RequestFormat =DataFormat.Json;
request.AddBody(user);
這裡備注一下以前犯的一個錯誤,用了AddBody方法必須添加 request.RequestFormat =DataFormat.Json; ,不然會出異常
我們看看下面的AddBody的源碼可以知道,除restsharp,.net第三方的網絡請求架構還有flurl.http。
1 /// <summary>
2 /// Serializes obj to format specified by RequestFormat, but passes xmlNamespace if using the default XmlSerializer
3 /// The default format is XML. Change RequestFormat if you wish to use a different serialization format.
4 /// </summary>
5 /// <param name="obj">The object to serialize</param>
6 /// <param name="xmlNamespace">The XML namespace to use when serializing</param>
7 /// <returns>This request</returns>
8 public IRestRequest AddBody(object obj, string xmlNamespace)
9 {
10 string serialized;
11 string contentType;
12
13 // TODO: Make it possible to change the serialiser
14 switch (RequestFormat)
15 {
16 case DataFormat.Json:
17 serialized = JsonSerializer.Serialize(obj);
18 contentType = JsonSerializer.ContentType;
19 break;
20
21 case DataFormat.Xml:
22 XmlSerializer.Namespace = xmlNamespace;
23 serialized = XmlSerializer.Serialize(obj);
24 contentType = XmlSerializer.ContentType;
25 break;
26
27 default:
28 serialized = "";
29 contentType = "";
30 break;
31 }
32
33 // passing the content type as the parameter name because there can only be
34 // one parameter with ParameterType.RequestBody so name isn't used otherwise
35 // it's a hack, but it works :)
36 return AddParameter(contentType, serialized, ParameterType.RequestBody);
37 }
38
39 /// <summary>
40 /// Serializes obj to data format specified by RequestFormat and adds it to the request body.
41 /// The default format is XML. Change RequestFormat if you wish to use a different serialization format.
42 /// </summary>
43 /// <param name="obj">The object to serialize</param>
44 /// <returns>This request</returns>
45 public IRestRequest AddBody(object obj)
46 {
47 return AddBody(obj, "");
48 }
49
50 /// <summary>
51 /// Serializes obj to JSON format and adds it to the request body.
52 /// </summary>
53 /// <param name="obj">The object to serialize</param>
54 /// <returns>This request</returns>
55 public IRestRequest AddJsonBody(object obj)
56 {
57 RequestFormat = DataFormat.Json;
58
59 return AddBody(obj, "");
60 }
3.HttpClient
性能上不如httpwebrequest,用的非常少,據說使用的時候要注意不少,這裡隻是寫一個簡單的例子,不喜勿噴。
需要添加引用System.Http.Http
1 public class HttpClientUtil
2 {
3 public static async System.Threading.Tasks.Task<byte[]> GetBytes(string path)
4 {
5 HttpClient client = new HttpClient();
6 try
7 {
8 HttpResponseMessage response = await client.GetAsync(path);
9 if (response.StatusCode == System.Net.HttpStatusCode.OK)
10 {
11 byte[] bytes = await response.Content.ReadAsByteArrayAsync();
12 return bytes;
13 }
14 return null;
15 }
16 catch (Exception ex)
17 {
18 return null;
19 }
20 finally
21 {
22 client.Dispose();
23 }
24 }
25
26 public static async System.Threading.Tasks.Task<bool> PostForm(string path, Dictionary<string,string> _params)
27 {
28
29 var handler = new HttpClientHandler() { AutomaticDecompression = System.Net.DecompressionMethods.GZip };
30 HttpClient client = new HttpClient();
31 try
32 {
33 client.Timeout = TimeSpan.FromSeconds(5);
34 //HttpContent httpContent = new StringContent(postData);
35 //httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded");
36 HttpContent httpContent = new FormUrlEncodedContent(_params);
37 var response = await client.PostAsync(path, httpContent);
38 if (response.StatusCode == System.Net.HttpStatusCode.OK)
39 {
40 string result = await response.Content.ReadAsStringAsync();
41 result = JsonConvert.DeserializeObject<string>(result);
42 if (result == "success")
43 return true;
44 return false;
45 }
46 return false;
47 }
48 catch (Exception ex)
49 {
50 return false;
51 }
52 finally
53 {
54 client.Dispose();
55 }
56 }
57 }
上面介紹了三種.net方面的網絡請求的方法,下面就來說說android方面的網絡請求HttpUrlConnection、第三方okhttp。
4.HttpURLConnection
httpURLConnection和HttpWebRequest很相似,是java平台上的一種多用途、輕量級的http用戶端,提供的api都非常簡單,這一點也是好處,可以使得我們非常友善去拓展他。下面我們簡單看下如何使用HttpURLConnection。
引用來自:Java.Net
- HttpURLConnection conn = (HttpURLConnection)url.OpenConnection();建立一個URL對象
- conn.ConnectTimeout = 5000; conn.RequestMethod = “get”;設定請求方式和連接配接逾時的時間
- inputStream = conn.InputStream;擷取伺服器傳回的輸入流
- conn.Disconnect();最後調用disconnect方法将http連接配接關掉
public class HttpUrlConnecUtil
{
/// <summary>
/// get方式擷取byte 數組
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static byte[] getImage(string path)
{
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection)url.OpenConnection();
conn.ConnectTimeout = 5000;
conn.RequestMethod = "GET";//小寫會報錯
System.IO.Stream inputStream=null;
try
{
if (conn.ResponseCode == HttpStatus.Ok)
{
inputStream = conn.InputStream;
return StreamUtil.StreamToBytes(inputStream);
}
return null;
}
catch (Exception ex)
{
return null;
}
finally
{
inputStream.Close();
conn.Disconnect();
}
}
public static string post(string path,string name,string pwd)
{
string result = string.Empty;
HttpURLConnection conn = (HttpURLConnection)new URL(path).OpenConnection();
conn.RequestMethod = "POST";
conn.ReadTimeout = 5000;
conn.ConnectTimeout = 5000;
//設定運作輸入、輸出
conn.DoOutput = true;
conn.DoInput = true;
//post 方式不能緩存,需要手動設定false
conn.UseCaches = false;
string data = "name=" + URLEncoder.Encode(name, "UTF-8") + "&pwd=" + URLEncoder.Encode(pwd,"UTF-8");
Stream outSteam=null;
//擷取輸出流
try
{
outSteam = conn.OutputStream;
outSteam.Write(Encoding.UTF8.GetBytes(data), 0, data.Length);
outSteam.Flush();
if (conn.ResponseCode == HttpStatus.Ok)
{
Stream input = conn.InputStream;
byte[] bytes = StreamUtil.StreamToBytes(input);
result = bytes.ToString();
}
return result;
}
catch (Exception ex)
{
return "";
}
finally {
outSteam.Close();
conn.Disconnect();
}
}
}
/// <summary>
/// 将流轉成byte數組
/// </summary>
/// <param name="stream"></param>
/// <param name="bytes"></param>
public static byte[] StreamToBytes(Stream stream)
{
MemoryStream memoryStream = new MemoryStream();
byte[] buffer = new byte[64 * 1024];
int i;
try
{
while ((i = stream.Read(buffer, 0, buffer.Length)) > 0)
{
memoryStream.Write(buffer, 0, i);
}
var bytes = memoryStream.ToArray();
return bytes;
}
catch (Exception ex)
{
return null;
}
finally {
memoryStream.Close();
stream.Close();
}
}
5.OkHttp 最火的android網絡請求架構
okhttp是一個第三方的網絡請求架構,被廣泛适用于android中請求網絡資料,是一個一個輕量級的架構,有移動支付Square公司貢獻(Picasso和LeakCanary),和HttpURLConnection和api是一緻的。在xamarin android中使用的時候需要在nuget中添加引用OkHttp,命名空間:using Square.OkHttp3;
okhttp官網:
http://square.github.io/okhttp/ https://github.com/square/okhttp除了okhttp外,android中比較流行的網絡請求架構還有
retrofit,retrofit2依賴于okhttp;github位址:
http://square.github.io/retrofit/,拓展性比較強
volley:google在2013年推出的android異步網絡請求架構和圖檔加載架構
下面看看,如何在xamarin android中使用okhttp發送get,post請求吧。
public class OkHttpClientUtil
{
private OkHttpClient httpClient;
public OkHttpClientUtil()
{
httpClient = new OkHttpClient.Builder()
.ConnectTimeout(5, TimeUnit.Seconds)//連接配接逾時5秒
.WriteTimeout(5, TimeUnit.Seconds)//寫入資料逾時5秒
.ReadTimeout(5, TimeUnit.Seconds)//讀取資料逾時5秒
.Build();
}
public static OkHttpClientUtil Instance()
{
return new OkHttpClientUtil();
}
public async System.Threading.Tasks.Task<bool> Post(string url, User user)
{
FormBody.Builder formBody = new FormBody.Builder(); //建立表單請求體
formBody.Add("name", user.Name);
formBody.Add("pwd", user.Pwd);
Request request = new Request.Builder().AddHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8").Url(url).Post(formBody.Build()).Build();
var response = await httpClient.NewCall(request).ExecuteAsync();
if (response.Code() == 200)
{
var result =JsonConvert.DeserializeObject<string>(response.Body().String());
if (result == "success")
{
return true;
}
return false;
}
return false;
}
public async System.Threading.Tasks.Task<byte[]> Get(string url)
{
Request request = new Request.Builder().Url(url).Build();
Response response = await httpClient.NewCall(request).ExecuteAsync();
if (response.Code() == 200)
{
var stream = response.Body().ByteStream();
var bytes = StreamUtil.StreamToBytes(stream);
return bytes;
}
return null;
}
}