中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用ASP.Net?WebAPI構建REST服務

發布時間:2022-06-14 11:40:15 來源:億速云 閱讀:206 作者:iii 欄目:開發技術

這篇文章主要介紹了如何使用ASP.Net WebAPI構建REST服務的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇如何使用ASP.Net WebAPI構建REST服務文章都會有所收獲,下面我們一起來看看吧。

一、創建WebAPI應用程序

1、Web API 1版本

首先創建一個Asp.Net MVC 4 Web應用程序(我這里用的是Visual Studio 2012)。

如何使用ASP.Net?WebAPI構建REST服務

在出來的模板中選擇Web API。點擊確定后,就創建了一個空的WebAPI服務。

如何使用ASP.Net?WebAPI構建REST服務

2、Web API 2版本

如何使用ASP.Net?WebAPI構建REST服務

點擊確定后,就創建了一個空的WebAPI服務。此時只有一個空項目,還沒有任何功能

在進行下一步之前,首先我們來看一下REST的基本操作模型,大致可以分為如下四種:

  • POST — 創建資源

  • GET — 檢索資源

  • PUT — 更新資源

  • DELETE — 刪除資源

非常經典的CRUD模型。

在Web API中實現這樣一個的模型是非常簡單的,直接使用向導建一個Controller即可

如何使用ASP.Net?WebAPI構建REST服務

如何使用ASP.Net?WebAPI構建REST服務

在Web API中生成默認的ValuesController

如何使用ASP.Net?WebAPI構建REST服務

默認的模板內容如下:

public class ValuesController : ApiController
{
        // GET api/values
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/values/5
        public string Get(int id)
        {
            return "value";
        }

        // POST api/values
        public void Post([FromBody]string value)
        {
        }

        // PUT api/values/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/values/5
        public void Delete(int id)
        {
        }
}

這其實已經幫我們實現了一個最基本的服務了,不過這個服務中只實現了Get,它支持如下兩種中方式的URL訪問(其它的方式也能訪問,但沒有具體的效果):

  • api/values 訪問所有的Value列表

  • api/values/{id} 根據ID訪問Value

按Ctrl + F5中執行,在瀏覽器中輸入相應的地址即可看到結果

如何使用ASP.Net?WebAPI構建REST服務

下面我們要做的就是完善它,實現一個簡單的查詢功能,這里我引用了微軟官方的一個例子:

public class ProductsController : ApiController
{
        Product[] products = new Product[]
        {
            new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },
            new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },
            new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }
        };

        public IEnumerable Get()
        {
            return products;
        }

        public IHttpActionResult Get(int id)
        {
            var product = products.FirstOrDefault((p) => p.Id == id);
            if (product == null)
            {
                return NotFound();
            }
            return Ok(product);
        }
}

public class Product
{
        public int Id { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
}

此時,我們就可以在瀏覽器中看到結果了(由于Controller改名字了,此時的地址就變成了api/products)

如何使用ASP.Net?WebAPI構建REST服務

到此為止,一個基于Asp.net Web API的 簡單的REST Web服務就構建完成了,由于篇幅所限,這里就不做更多的介紹了,跟多信息可以參看微軟官方文檔:Getting Started with ASP.NET Web API 2。

備注:WebAPI升級到 WebAPI 2如下命令更新web Api:

Install-Package Microsoft.AspNet.WebApi

二、路由

REST并沒有像傳統的RPC服務那樣顯式指定了服務器函數的訪問路徑,而是將URL根據一定的規則映射為服務函數入口,這個規則就稱之為路由。Asp.Net WebAPI的路由方式和Asp.Net MVC是相同的,它支持兩種路由方式,傳統的路由映射和特性路由。 路由規則WebApiConfig.cs中定義。

如何使用ASP.Net?WebAPI構建REST服務

它的默認內容如下:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

它默認注冊了兩種路由規則,第一行注冊的是特性路由,第二行注冊的則是傳統的映射路由。默認情況下,由于我們沒有編寫特性路由規則,則是按照傳統的Controller方式映射路由。

關于路由規則,MSDN文檔ASP.NET 路由介紹得非常詳細,但由于其介紹得太詳細了,反而不容易得其門而入,這里我只拿默認的路由規則來簡單但的介紹一下我的理解,它的uri格式是這樣的"api/{controller}/{id}",其中id是可選的。拿前文的例子來說吧,

  • 當我們對api/products地址進行訪問的時候,系統則會首先找到名為ProductsController的控制器。

  • 然后,根據訪問方式查找函數,由于這里是Get操作,則查找Get開頭的函數, 這里會找到Get()和Get(int id)兩個重載版本。

  • 最后,根據參數來匹配具體的函數,因為這里沒有帶參數id。因此匹配到了Get()函數,返回了所有的集合。

另外,這里也有幾個常用的衍生規則:

  • 根據操作方式找函數的時候,只需要匹配首部即可,因此我們編寫函數的時候寫成Get()和GetProduct()都是可以的。,

  • 根據操作方式找函數的時候查找的時候不分大小寫,因此寫成Get()或get()都是可以的

當我們使用帶參數的版本時候,也有幾個需要注意的地方:

  • 參數名不分大小寫,我們寫成id或ID都是可以的

  • 參數名要求嚴格匹配的,我們寫成ID2是不行的,此時則會匹配到錯誤的結果Get()

默認的規則雖然大多數的時候還是比較方便的,但是很多時候我們需要手動指定個性化的路由規則。例如,我們可以自定義一個按名稱來查詢的url:api/products/name=xxx。這個時候則可以用特性路由快速的實現了:

[Route("api/{controller}/name={name}")]
public IHttpActionResult GetByName(string name)

三、返回值

Asp.Net WebAPI服務函數的返回值主要可以分為void、普通對象、HttpResponseMessag、IHttpActionResult e四種,本文這里簡單的介紹一下它們的區別。

1、返回void

返回void一般常用于Put和Delete函數。

public void Delete(int id)
{
}

當服務函數執行完成后,服務器端并不是啥都不干直接把客戶端給斷掉,而是發送一個標準的204 (No Content)的Http應答給客戶端。

HTTP/1.1 204 No Content
    Cache-Control: no-cache
    Pragma: no-cache
    Expires: -1
    Server: Microsoft-IIS/8.0
    X-AspNet-Version: 4.0.30319
    X-SourceFiles: =?UTF-8?B?Zjpc5paH5qGjXHZpc3VhbCBzdHVkaW8gMjAxM1xQcm9qZWN0c1xXZWJBcHBsaWNhdGlvbjFcV2ViQXBwbGljYXRpb24xXGFwaVx2YWx1ZXNcMQ==?=
    X-Powered-By: ASP.NET
    Date: Fri, 02 May 2014 13:32:07 GMT

2、返回普通對象

返回普通對象時,服務器將返回的對象序列化后(默認是json),通過Http應答返回給客戶端。例如,

public class ValuesController : ApiController
{
        public string Get()
        {
            return "hello";
        }
}

此時的返回結果是:

HTTP/1.1 200 OK
    Cache-Control: no-cache
    Pragma: no-cache
    Content-Type: application/json; charset=utf-8
    Expires: -1
    Server: Microsoft-IIS/8.0
    X-AspNet-Version: 4.0.30319
    X-SourceFiles: =?UTF-8?B?Zjpc5paH5qGjXHZpc3VhbCBzdHVkaW8gMjAxM1xQcm9qZWN0c1xXZWJBcHBsaWNhdGlvbjFcV2ViQXBwbGljYXRpb24xXGFwaVx2YWx1ZXM=?=
    X-Powered-By: ASP.NET
    Date: Fri, 02 May 2014 12:54:18 GMT
    Content-Length: 7
"hello"

異步返回普通對象:

WebAPI也是支持異步返回對象的:

    public async Task<string> Get()
    {
        await Task.Delay(100);
        return "hello";
    }

異步返回的時候,服務器異步等待函數執行完成后再將返回值返回給對象。由于這個過程對于客戶端來說是透明的,這里就不列舉報文了。

3、返回HttpResponseMessage

HttpResponseMessage是標準Http應答了,此時服務器并不做任何處理,直接將HttpResponseMessage發送給客戶端。

public HttpResponseMessage Get()
{
        var response = Request.CreateResponse(HttpStatusCode.OK);
        response.Content = new StringContent("hello", Encoding.UTF8);
            
        return response;
}

此時的返回結果如下:

HTTP/1.1 200 OK
    Cache-Control: no-cache
    Pragma: no-cache
    Content-Length: 5
    Content-Type: text/plain; charset=utf-8
    Expires: -1
    Server: Microsoft-IIS/8.0
    X-AspNet-Version: 4.0.30319
    X-SourceFiles: =?UTF-8?B?Zjpc5paH5qGjXHZpc3VhbCBzdHVkaW8gMjAxM1xQcm9qZWN0c1xXZWJBcHBsaWNhdGlvbjFcV2ViQXBwbGljYXRpb24xXGFwaVx2YWx1ZXM=?=
    X-Powered-By: ASP.NET
    Date: Fri, 02 May 2014 13:09:57 GMT
hello

可以看到,這里返回的content-type仍然是原始定義的text類型,而不是json。要實現想上面的例子所示的結果,則需要將Get函數改寫為如下形式

public HttpResponseMessage Get()
{
        return Request.CreateResponse(HttpStatusCode.OK, "hello");
}

4、返回IHttpActionResult

IHttpActionResult是Web API 2 中引入的一個接口,它的定義如下:

public interface IHttpActionResult
{
        Task ExecuteAsync(CancellationToken cancellationToken);
}

從它的定義可以看出,IHttpActionResult是HttpResponseMessage的一個工廠類,最終還是用于構建HttpResponseMessage返回,由于它可以取消,因而可以實現更為強大的返回功能(如流傳輸)。當服務函數返回IHttpActionResult對象時,服務器執行該對象的ExecuteAsync函數,并異步等待至函數完成后,獲取其返回值HttpResponseMessage輸出給客戶端。

IHttpActionResult是WebAPI中推薦的標準返回值,ApiController類中也提供了不少標準的工廠函數方便我們快速構建它們,如BadRequest,Conflict,Ok,NotFound等,一個簡單的示例如下:

public IHttpActionResult Get(int id)
{
        var product = products.FirstOrDefault((p) => p.Id == id);
        if (product == null)
        {
            return NotFound();
        }
        return Ok(product);
}

四、參數綁定

1、默認綁定方式

WebAPI把參數分成了簡單類型和復雜類型:

  • 簡單類型主要包括CLR的primitive types,(int、double、bool等),系統內置的幾個struct類型(TimeSpan、Guid等)以及string。對于簡單類型的參數,默認從URI中獲取。

  • 復雜類型的數據也可以直接作為參數傳入進來,系統使用media-type formatter進行解析后傳給服務函數。對于復雜類型,默認從正文中獲取。

例如,對于如下函數

HttpResponseMessage Put(int id, Product item)

其id默認從url中獲取,其item默認從正文中獲取。

2、使用 [FromUri] 標記從URI中綁定參數

我們可以使用 [FromUri] 標記強制從URI中綁定參數,例如

public class GeoPoint
{
        public double Latitude { get; set; }
        public double Longitude { get; set; }
}

public ValuesController : ApiController
{
        public HttpResponseMessage Get( [FromUri]  GeoPoint location) { ... }
}

這樣,Get參數就是從URI中獲取了讀取GeoPoint對象。需要注意的是,此時我們必須將GeoPoint對象的屬性在URI中傳入: http://localhost/api/values/?Latitude=47.678558&Longitude=-122.130989 。

這種默認的序列化方式比較冗長,我們也可以自定義反序列化格式為類似這樣的形式:http://localhost/api/values/?location=47.678558,-122.130989。

3、使用 [FromBody] 標記從正文中綁定參數

同樣,我們可以使用 [FromBody] 標記強制從正文中綁定參數,例如

public HttpResponseMessage Post( [FromBody] string name)

將強制從FormData等非URL參數中讀取數據

如何使用ASP.Net?WebAPI構建REST服務

4、綁定多個參數

前面介紹的方式中,只能從URI中綁定一個參數,雖然可以通過傳入復雜類型解決多參數的問題,但很多時候不如在URI中來得直接。此時,我們則可以使用前面介紹的特性路由來實現多參的綁定,例如:

[Route("api/{controller}/{year}/{month}/{day}")]
public string Get(int year, int month, int day)
{
        return string.Join(",", year, month, day);
}

五、客戶端

WebAPI是標準的Http協議,支持Http協議的客戶端(如瀏覽器)都可以訪問。但是,有的時候我們如果想在自己的程序中使用WebAPI時,此時就要實現自己的客戶端了。

1、使用HttpClient庫

我之前介紹過在.Net 4.5中新增的HttpClient庫,它對Http操作實現了非常好的封裝。我們可以通過它實現Http訪問,例如,我們對前文所示的API進行一次Post操作:

// POST: api/Values
public void Post(Product value)
{
}

首先對HttpClient進行一些初始化操作:

var client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:1282/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

這里主要進行了兩部操作:1. 定義了默認的基地址,減少后續的URL長度,2. 定義了默認的接受的數據類型為Json。

下一步就要開始對Product對象的內容編碼,默認是xml或json,這里我選擇相對簡單的json:

var product = new Product() { Id = 1, Name = "food" };
var content = Newtonsoft.Json.JsonConvert.SerializeObject(product);
var httpContent = new StringContent(content, Encoding.UTF8);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json") { CharSet = "utf-8" };
await httpContent.LoadIntoBufferAsync();
var rsp = await client.PostAsync("api/values", httpContent);

從上面的代碼可以看出,由于WebAPI不像WCF那樣能自動生成客戶端代碼,需要我們自己封裝對象,上面光封裝對象就用了四行代碼,對于不熟悉HttpClient朋友來說還是比較容易出錯的。因此微軟提供了一系列擴展函數方便我們簡化這一過程。

2、使用WebApi.Client庫

在Nuget中安裝WebApi.Client庫

如何使用ASP.Net?WebAPI構建REST服務

這個庫安裝后會在引用中增加一個System.Net.Http.Formatting的程序集,它主要提供了一系列擴展函數(其實裝這個庫順帶也會把HttpClient和Json.Net一并安上),現在上面的代碼就可以簡化如下了:

var product = new Product() { Id = 1, Name = "food" };
var rsp = await client.PostAsJsonAsync("api/values", product);

除了PostAsJsonAsync這個擴展函數外,還提供了PostAsXmlAsync這種以XML傳輸的方式。同樣,Put也有PutAsJsonAsync和PutAsXmlAsync的擴展版本。對于Get,雖然也提供了擴展函數,但是使用的方式稍有不同:

var rsp = await client.GetAsync("api/values/1");
rsp.EnsureSuccessStatusCode();
var product = await rsp.Content.ReadAsAsync();

對于Delete,卻沒有提供擴展函數,可能是官方認為Delete直接在URL中就傳ID就夠用了,沒必要在Request中封裝消息了吧。

六、Self-Host

Asp.Net WebAPI生成的是一個程序集,并不是獨立的進程,因此,要運行的時候必須將其承載在相應的宿主上,一般比較常見的是IIS承載。

很多時候,我們為了簡化部署或者功能集成,需要將其承載到獨立的進程上,這種方式一般稱之為Self-Host,本文就簡單的介紹一下WebAPI的SefHost方法。

首先在Nuget上安裝Microsoft.AspNet.WebApi.SelfHost庫。

如何使用ASP.Net?WebAPI構建REST服務

附上我們的WebAPI控制器

public class ValuesController : ApiController
{
    public IEnumerable<string> Get()
    {
        return new string[] { "111", "222" };
    }
}

接下來的工作就是啟動我們的服務器了。

    class Program
    {
        static void Main(string[] args)
        {
            //Assembly.Load("WebApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");    //加載外部程序集
            var config = new HttpSelfHostConfiguration("http://localhost:8080");

            config.Routes.MapHttpRoute(
                "API Default", "api/{controller}/{id}",
                new { id = RouteParameter.Optional });

            using (var server = new HttpSelfHostServer(config))
            {
                server.OpenAsync().Wait();
                Console.WriteLine("Press Enter to quit.");
                Console.ReadLine();
            }
        }
    }

從上面的代碼可以看出,配置文件和Asp.Net程序中基本上是一樣的,如果是直接用Asp.Net項目中生成的DLL的話,我們也可以直接用其WebApiConfig.Register的方法來進行配置的(需要像第一行注掉的那樣使用Assembly.Load加載程序集)。下面一段就是啟動服務器了,更多內容可以參看MSDN文檔:http://www.asp.net/web-api/overview/hosting-aspnet-web-api/self-host-a-web-api

值得一提的是,SelfHost是在一個獨立進程中啟動了Http服務,也可以是說,它是一個mini版的Http服務器,我之前介紹過通過HttpListener實現簡單的Http服務,到了現在,用WebAPI的SelfHost方式是可以更加快捷的實現擴展性更好的Mini Http服務器的,當我們需要一個簡單的Http服務的時候,可以使用這種方式。

除了這種方式外,微軟更加推薦用功能更加強大的OWIN來承載WebAPI服務。

另外,除了IIS、SelfHost等方式外,云時代發布到Windows Azure也是非常便捷的,這里就不做多少介紹了。

七、調試工具

由于WebAPI本身是基于HTTP協議的,在開發過程中,我們可以使用瀏覽器或Fiddler等HTTP工具輔助開發。與此同時,微軟也提供了一些工具方便我們調試,使得開發更加簡單快捷,本文就簡單的介紹一下這幾個工具。

1、幫助文檔

通過幫助文檔,我們可以非常直觀的看到控制器生成了那些路由,通過這些接口文檔可以非常方便的指導客戶端開發。

如何使用ASP.Net?WebAPI構建REST服務

2、路由調試器

當我們應用了大量的路由規則和自定義路由的時候,有的時候,就會出現一條路由具體走的那條規則的情況,這個時候,則可以通過路由調試器來幫助我們進行分析和定位:

如何使用ASP.Net?WebAPI構建REST服務

3、執行過程跟蹤

執行過程跟蹤工具則可以非常直觀的打印出其交互過程,可以非常方便的查看我們是否進行了正確的輸入和獲得了相應的輸出。

如何使用ASP.Net?WebAPI構建REST服務

關于“如何使用ASP.Net WebAPI構建REST服務”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“如何使用ASP.Net WebAPI構建REST服務”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

东城区| 灵石县| 湄潭县| 隆林| 枣阳市| 曲松县| 巴林右旗| 德阳市| 元氏县| 米易县| 屏东县| 丰县| 商水县| 家居| 库伦旗| 龙泉市| 色达县| 龙陵县| 紫阳县| 旬邑县| 泸西县| 遂平县| 湖南省| 贵定县| 新乡县| 扶绥县| 连城县| 尚义县| 弥渡县| 文登市| 霍林郭勒市| 梓潼县| 娄烦县| 英吉沙县| 云阳县| 济宁市| 舒城县| 呼图壁县| 闵行区| 井研县| 白朗县|