首頁 >後端開發 >C#.Net教程 >ASP.NET WEB API的適用場景第一個實例

ASP.NET WEB API的適用場景第一個實例

PHPz
PHPz原創
2017-04-04 15:52:233159瀏覽

在我前一篇部落格中已經給各位簡單介紹了HTTP協定與RestFul API的關係,以及一些基本的HTTP協定知識,在這些知識的鋪墊下,今天,我們一起來討論一下WEB API的適用場景,然後寫我們第一個WEB API接口,並示範如何對其進行簡單呼叫。

       很多人都很迷惑,既然有了WCF為什麼還要有WEB API? WEB API會不會取代WCF?

       就我的看法,WCF提供的是一種RPC實現的集合,WCF的設計更多地考慮了SOA的場景,以及各種RPC的問題。很多人也會說,RestFul API也是一種RPC啊,而WCF中也有關於RestFul 的實作啊。很多資料中RPC和RestFul在風格概念上是有一些區別的,其實我覺得這兩者的區別比較主觀,過度糾結這些就學院派了;我主要關注了實際使用上的一些問題,在WCF中,支援的協議很多,WS-*系列協議,以及一些更簡潔的協議,其中提供了一些專用通信協議的性能是非常高的,並且WCF還提供了服務發現等功能,我認為WCF更適合內部系統間的高效能調用,社區中也有其他一些RPC方案可以選擇,例如gRPC,Avor,thrift都是和WCF定位相同的產品;而WEB API是關注於HTTP RestFul風格的產品,在此基礎上,任何語言、任何終端都能非常容易地進行對接,並且能利用非常成熟的各種HTTP基礎設施和解決方案來進行開發、調試、負載平衡、內容分發。所以,WEB API是一種針對HTTP的,偏重於快速開發RestFul風格開放式API的開發框架。目前看來,他並不能取代WCF,他們各有適合的場景,不能認為WEB API是WCF的替代產品。

       OK,現在我們來開發第一組WEB API介面!使用VS2012以後的版本都有現成的WEB API創建模板,大家跟著創建就好了,創建出來後,專案中會有MVC、WEB API的項目,WEB API對MVC有依賴,不能單獨創建!而WEB API和MVC都是利用類似的路由機制,所以在預設路由中,WEB API 使用


/api/{controller}/{id}

 

       作為路由,新增了/ api/節以區分MVC和web api。

       接下來,我們新增一個WEB API的Controller,取名為PersonController,祂繼承於ApiController;創造這個Controller的時候,我們定義了一個資源:Person,在PersonController裡的所有操作均圍繞著Person這個資源來的。接下來我們開始定義一組增刪改查操作。

       在Web API中,預設路由採用了一種約定:根據謂詞來進行路由,而方法名稱的前綴就是呼叫此方法對應所使用的HTTP謂詞。程式碼範例如下:

      


#
/// <summary>

    /// Person 为资源,对Person进行的一组操作    /// </summary>

    public class PersonController : ApiController

    {        private static List<Person> _personLst = new List<Person>();       

        /// <summary>

        /// 获取一个Person        /// </summary>

        /// <param name="id">Person的ID</param>

        /// <returns>Person</returns>

        public Person GetPerson(long id)

        {            return _personLst.Find(x => x.Id == id);

        } 

        /// <summary>

        /// 添加一个Person        /// </summary>

        /// <param name="person">Person</param>

        public void PostAddPerson(Person person)

        {

            _personLst.Add(person);

        } 

        /// <summary>

        /// 修改一个        /// </summary>

        /// <param name="id">Person Id</param>

        /// <param name="person">新</param>

        public void PutModifyPerson(long id, Person person)

        {            var p = _personLst.Find(x => x.Id == id);

            p.Age = person.Age;

            p.Name = person.Name;

            p.Sex = person.Sex;

        } 

        /// <summary>

        /// 删除一个Person        /// </summary>

        /// <param name="id">Person ID</param>

        public void DeletePerson(long id)

        {

            _personLst.RemoveAll(x => x.Id == id);

        }

}

 

一個簡單的針對資源的CRUD操作的API就好了,不用解析輸入,不用拼接輸出,就是這麼簡單!讓我們來遛一遛!

 

傳送請求:謂詞為POST,語意建立Person,Person描述在Body裡,head中宣告了Body透過Json序列化。

收到回應:回應碼204,屬於2XX型別執行成功,Body裡沒有資料

 

傳送請求:謂詞為GET,語意為查詢Person資源,Id為1的,head中宣告希望接收使用XML序列化的資料

收到回應:回應碼為200,執行成功,Body中有數據,資料使用XML序列化

 

傳送請求:謂詞為PUT,語意為修改ID為1的Person資源,修改內容在Body中,Content-Type標示Body使用Json序列化,在Body中我們將Name修改為Test1Changed

收到回應,回應碼為204,執行成功

 

傳送請求:謂詞為GET,語意為查詢ID為1的Person資源,Accept標示希望接收到Json資料

收到回應:可以看到Body為使用Json序列化的內容,Name屬性已經變更為Test1Changed

 

#傳送請求:謂詞為DELETE,語意為刪除ID為1的Person資源

收到回應:回應碼204,執行成功

 

发送请求:谓词为GET,语义为查询ID为1的Person资源,Accept标明希望接收到Json数据

收到响应:响应码为200,执行成功,响应内容为null,资源已删除

 

这就是我用Fiddler来发送、调用的一组RestFul接口,大家可以看到,整个调用过程使用到了HTTP的语义,用到了谓词路由、内容协商。在增、删、改操作中,我都是使用void作为返回值,根据HTTP Code 判断,大家也可以自定义一些返回数据来做出更进一步的操作描述。

 

在写了这些API后,我们需要在程序中调用,我以C#为例写一组对这些接口调用的实现。在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了。

       在使用中,System.Net.Http这个程序集提供了HttpClient类以及相关的HTTP调用,而System.Net.Http.Formatting提供了一些针对HttpClient的帮助扩展,更好地支持了内容协商、Content创建等功能。下面我就和大家一起写一下这个例子:

       我们新建一个控制台程序:

       代码如下:


public class Person

    {        public long Id { get; set; }        public string Name { get; set; } 

        public int Age { get; set; } 

        public string Sex { get; set; } 

        public override string ToString()

        {            return $"Id={Id} Name={Name} Age={Age} Sex={Sex}";

        }

    } 

    class Program

    {        static void Main(string[] args)

        {            var client = new HttpClient();

 

            client.BaseAddress = new Uri("http://localhost:22658/"); //基本的API URL
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); //默认希望响应使用Json序列化
 

 

            Run(client);

 

            Console.ReadLine();

 

        } 

        static async void Run(HttpClient client)

        {            var result = await AddPerson(client);

            Console.WriteLine($"添加结果:{result}"); //添加结果:true

 

            var person = await GetPerson(client);

            Console.WriteLine($"查询结果:{person}"); //查询结果:Id=1 Name=test Age=10 Sex=F
 

            result = await PutPerson(client);

            Console.WriteLine($"更新结果:{result}"); //更新结果:true
 

            result = await DeletePerson(client);

            Console.WriteLine($"删除结果:{result}"); //删除结果:true
        } 

        static async Task<bool> AddPerson(HttpClient client)

        {            return await client.PostAsJsonAsync("api/Person", new Person() { Age = 10, Id = 1, Name = "test", Sex = "F" }) //向Person发送POST请求,Body使用Json进行序列化
                                     .ContinueWith(x => x.Result.IsSuccessStatusCode);  //返回请求是否执行成功,即HTTP Code是否为2XX
        } 

        static async Task<Person> GetPerson(HttpClient client)

        {            return await await client.GetAsync("api/Person/1") //向Person发送GET请求
                .ContinueWith(x => x.Result.Content.ReadAsAsync<Person>(                              //获取返回Body,并根据返回的Content-Type自动匹配格式化器反序列化Body

                    new List<MediaTypeFormatter>() {new JsonMediaTypeFormatter()/*这是Json的格式化器*/

                                                    ,new XmlMediaTypeFormatter()/*这是XML的格式化器*/}));

 

        } 

        static async Task<bool> PutPerson(HttpClient client)

        {            return await client.PutAsJsonAsync("api/Person/1", new Person() { Age = 10, Id = 1, Name = "test1Change", Sex = "F" }) //向Person发送PUT请求,Body使用Json进行序列化
                                    .ContinueWith(x => x.Result.IsSuccessStatusCode);  //返回请求是否执行成功,即HTTP Code是否为2XX
        } 

        static async Task<bool> DeletePerson(HttpClient client)

        {            return await client.DeleteAsync("api/Person/1") //向Person发送DELETE请求
                .ContinueWith(x => x.Result.IsSuccessStatusCode); //返回请求是否执行成功,即HTTP Code是否为2XX
        }

}

 

    这就完成了这组API的调用,是不是非常简单方便?HTTPClient使用全异步的方法,并且他有良好的扩展性,我会在之后的博客中再聊这个问题。

    OK,到此为止一组简单的Restful API和C#的调用客户端就完成了,但这只是开始,Web API是一个很强大的框架,他的扩展点非常丰富,这些扩展能为我们的开发提供很多的帮助,下一篇博文我将为大家带来WEB API中Filter的使用。

    博文中如有不正确的地方欢迎大家指正。

以上是ASP.NET WEB API的適用場景第一個實例的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn