在C#中,傳統調用HTTP接口一般有兩種辦法:
WebRequest/WebResponse組合的方法調用
WebClient類進行調用。
第一種方法抽象程度較低,使用較爲繁瑣;而WebClient主要面向了WEB網頁場景,在模擬Web操作時使用較爲方便,但用在RestFul場景下卻比較麻煩,在Web API發佈的同時,.NET提供了兩個程序集:System.Net.Http和System.Net.Http.Formatting。這兩個程序集中最核心的類是HttpClient。在.NET4.5中帶有這兩個程序集,而.NET4需要到Nuget裏下載Microsoft.Net.Http和Microsoft.AspNet.WebApi.Client這兩個包才能使用這個類,更低的.NET版本就只能表示遺憾了只能用WebRequest/WebResponse或者WebClient來調用這些API了。
在WebApi發佈之前,我們都是通過WebRequest/WebResponse這兩個類組合來調用HTTP接口的
封裝一個RestClient類
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
namespace WebApplication1
{
public class RestClient
{
private string BaseUri;
public RestClient(string baseUri)
{
this.BaseUri = baseUri;
}
#region Get請求
public string Get(string uri)
{
//先根據用戶請求的uri構造請求地址
string serviceUrl = string.Format("{0}/{1}", this.BaseUri, uri);
//創建Web訪問對 象
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(serviceUrl);
//通過Web訪問對象獲取響應內容
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
//通過響應內容流創建StreamReader對象,因爲StreamReader更高級更快
StreamReader reader = new StreamReader(myResponse.GetResponseStream(),Encoding.UTF8);
//string returnXml = HttpUtility.UrlDecode(reader.ReadToEnd());//如果有編碼問題就用這個方法
string returnXml = reader.ReadToEnd();//利用StreamReader就可以從響應內容從頭讀到尾
reader.Close();
myResponse.Close();
return returnXml;
}
#endregion
#region Post請求
public string Post(string data, string uri)
{
//先根據用戶請求的uri構造請求地址
string serviceUrl = string.Format("{0}/{1}", this.BaseUri, uri);
//創建Web訪問對象
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(serviceUrl);
//把用戶傳過來的數據轉成“UTF-8”的字節流
byte[] buf = System.Text.Encoding.GetEncoding("UTF-8").GetBytes(data);
myRequest.Method = "POST";
myRequest.ContentLength = buf.Length;
myRequest.ContentType = "application/json";
myRequest.MaximumAutomaticRedirections = 1;
myRequest.AllowAutoRedirect = true;
//發送請求
Stream stream = myRequest.GetRequestStream();
stream.Write(buf,0,buf.Length);
stream.Close();
//獲取接口返回值
//通過Web訪問對象獲取響應內容
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
//通過響應內容流創建StreamReader對象,因爲StreamReader更高級更快
StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8);
//string returnXml = HttpUtility.UrlDecode(reader.ReadToEnd());//如果有編碼問題就用這個方法
string returnXml = reader.ReadToEnd();//利用StreamReader就可以從響應內容從頭讀到尾
reader.Close();
myResponse.Close();
return returnXml;
}
#endregion
#region Put請求
public string Put(string data, string uri)
{
//先根據用戶請求的uri構造請求地址
string serviceUrl = string.Format("{0}/{1}", this.BaseUri, uri);
//創建Web訪問對象
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(serviceUrl);
//把用戶傳過來的數據轉成“UTF-8”的字節流
byte[] buf = System.Text.Encoding.GetEncoding("UTF-8").GetBytes(data);
myRequest.Method = "PUT";
myRequest.ContentLength = buf.Length;
myRequest.ContentType = "application/json";
myRequest.MaximumAutomaticRedirections = 1;
myRequest.AllowAutoRedirect = true;
//發送請求
Stream stream = myRequest.GetRequestStream();
stream.Write(buf, 0, buf.Length);
stream.Close();
//獲取接口返回值
//通過Web訪問對象獲取響應內容
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
//通過響應內容流創建StreamReader對象,因爲StreamReader更高級更快
StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8);
//string returnXml = HttpUtility.UrlDecode(reader.ReadToEnd());//如果有編碼問題就用這個方法
string returnXml = reader.ReadToEnd();//利用StreamReader就可以從響應內容從頭讀到尾
reader.Close();
myResponse.Close();
return returnXml;
}
#endregion
#region Delete請求
public string Delete(string data, string uri)
{
//先根據用戶請求的uri構造請求地址
string serviceUrl = string.Format("{0}/{1}", this.BaseUri, uri);
//創建Web訪問對象
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(serviceUrl);
//把用戶傳過來的數據轉成“UTF-8”的字節流
byte[] buf = System.Text.Encoding.GetEncoding("UTF-8").GetBytes(data);
myRequest.Method = "DELETE";
myRequest.ContentLength = buf.Length;
myRequest.ContentType = "application/json";
myRequest.MaximumAutomaticRedirections = 1;
myRequest.AllowAutoRedirect = true;
//發送請求
Stream stream = myRequest.GetRequestStream();
stream.Write(buf, 0, buf.Length);
stream.Close();
//獲取接口返回值
//通過Web訪問對象獲取響應內容
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
//通過響應內容流創建StreamReader對象,因爲StreamReader更高級更快
StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8);
//string returnXml = HttpUtility.UrlDecode(reader.ReadToEnd());//如果有編碼問題就用這個方法
string returnXml = reader.ReadToEnd();//利用StreamReader就可以從響應內容從頭讀到尾
reader.Close();
myResponse.Close();
return returnXml;
}
#endregion
}
}
在Web API發佈的同時,.NET提供了兩個程序集:System.Net.Http和System.Net.Http.Formatting。這兩個程序集中最核心的類是HttpClient
以前的用法:創建一個控制檯程序,測試HTTP接口的調用。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WebApplication1;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
RestClient client = new RestClient("http://localhost:2444/");
string result = client.Get("api/Values");
Console.WriteLine(result);
Console.ReadKey();
}
}
}
.NET提供了兩個程序集:System.Net.Http和System.Net.Http.Formatting。這兩個程序集中最核心的類是HttpClient。在.NET4.5中帶有這兩個程序集,而.NET4需要到Nuget裏下載Microsoft.Net.Http和Microsoft.AspNet.WebApi.Client這兩個包才能使用這個類,更低的.NET版本就只能表示遺憾了只能用WebRequest/WebResponse或者WebClient來調用這些API了。
//控制檯代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using WebApplication1;
using WebApplication1.Models;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//RestClient client = new RestClient("http://localhost:2444/");
//string result = client.Get("api/Values");
//Console.WriteLine(result);
//Console.ReadKey();
var client = new HttpClient();
//基本的API URL
client.BaseAddress = new Uri("http://localhost:2444/");
//默認希望響應使用Json序列化(內容協商機制,我接受json格式的數據)
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//運行client接收程序
Run(client);
Console.ReadLine();
}
//client接收處理(都是異步的處理)
static async void Run(HttpClient client)
{
//post 請求插入數據
var result = await AddPerson(client);
Console.WriteLine($"添加結果:{result}"); //添加結果:true
//get 獲取數據
var person = await GetPerson(client);
//查詢結果:Id=1 Name=test Age=10 Sex=F
Console.WriteLine($"查詢結果:{person}");
//put 更新數據
result = await PutPerson(client);
//更新結果:true
Console.WriteLine($"更新結果:{result}");
//delete 刪除數據
result = await DeletePerson(client);
//刪除結果:true
Console.WriteLine($"刪除結果:{result}");
}
//post
static async Task<bool> AddPerson(HttpClient client)
{
//向Person發送POST請求,Body使用Json進行序列化
return await client.PostAsJsonAsync("api/Person", new Person() { Age = 10, Id = 1, Name = "test", Sex = "F" })
//返回請求是否執行成功,即HTTP Code是否爲2XX
.ContinueWith(x => x.Result.IsSuccessStatusCode);
}
//get
static async Task<Person> GetPerson(HttpClient client)
{
//向Person發送GET請求
return await await client.GetAsync("api/Person/1")
//獲取返回Body,並根據返回的Content-Type自動匹配格式化器反序列化Body內容爲對象
.ContinueWith(x => x.Result.Content.ReadAsAsync<Person>(
new List<MediaTypeFormatter>() {new JsonMediaTypeFormatter()/*這是Json的格式化器*/
,new XmlMediaTypeFormatter()/*這是XML的格式化器*/}));
}
//put
static async Task<bool> PutPerson(HttpClient client)
{
//向Person發送PUT請求,Body使用Json進行序列化
return await client.PutAsJsonAsync("api/Person/1", new Person() { Age = 10, Id = 1, Name = "test1Change", Sex = "F" })
.ContinueWith(x => x.Result.IsSuccessStatusCode); //返回請求是否執行成功,即HTTP Code是否爲2XX
}
//delete
static async Task<bool> DeletePerson(HttpClient client)
{
return await client.DeleteAsync("api/Person/1") //向Person發送DELETE請求
.ContinueWith(x => x.Result.IsSuccessStatusCode); //返回請求是否執行成功,即HTTP Code是否爲2XX
}
}
}
這個例子就是控制檯通過HttpClient這個類調用WebApi中的方法,WebApi就是項目新創建的ValuesController那個控制器,什麼都沒動,測試結果如下: