ASP.NET Web API 入門大雜燴

【前言】html

本文是大雜燴,意思便是:處處Copy再加一點點思考而混在一塊兒的文章,引用來源由於太多太雜故而省略,望原做者原諒。前端

【概述】web

ASP.NET Web APIASP.NET MVC 4一塊兒發行。它遵循REST架構風格,取WCF Web APIASP.NET MVC精華,又去除WCF自己較爲繁瑣的配置問題,專一於提供HTTP Service,只面向Http通訊協議,使得可快速開發出自身使用或對外公開的Web API。前端應用只要能發出HTTPURI請求(例如:http://domain/api/products)向Web API請求服務便可取得如JSONXML或自定義數據源。 數據庫

ASP.NET Web APIWeb API 的開發相似於 ASP.NET MVC 中控制器的開發,可是Web API 封裝了數據的序列化、反序列化,接口、實現都更加簡單。 簡單地說,若是要向瀏覽器、移動端等普遍的客戶端提供 Json/xml 數據格式,則應首選 ASP.NET Web API。api

從 .NET 3.5 開始 WCF 框架已經支持用 WebHttpBinding 構建創建在 WCF Message 棧上的 RESTful Web服務。由於 REST 的工做原理不一樣,不須要依賴 SOAP 協議,所以 WCF 消息管道對它作了特殊的優化。但 REST 集成在 WCF 消息管道上仍是不理想,因此微軟提出在 ASP.NET 平臺上構建REST,也就有了如今中的 Web Api。數組

【入門】瀏覽器

 一、首先確保開發環境符合微軟的要求:服務器

  • Visual Studio 2012
  • Visual Studio Express 2012 for Web
  • Visual Studio 2010 with ASP.NET MVC 4 installed.(安裝了ASP.NET MVC 4的VS 2010)
  • Visual Web Developer 2010 Express with ASP.NET MVC 4 installed.(安裝了ASP.NET MVC 4的VS 2010 Web開發者簡裝版)

二、新建Web API項目架構

圖一、建立項目框架

圖2.選擇Web API項目模板

 

三、添加一個模型

模型是表示應用程序數據的一種對象。ASP.NET Web API能夠自動把模型序列化成JSON、XML、或某些其它格式而後寫到HTTP響應的消息體中。只要客戶端可以讀取這種序列化格式,它就能夠進行反序列化獲取對象信息。另外一方面,設置HTTP請求消息中的Accept報頭,客戶端可以指示它所但願的是哪種格式。

圖3.添加模型

將這個類命名爲「Product」,並添加以下屬性:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace HelloWebAPI.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
    }
}

四、添加控制器

控制器是一種處理HTTP請求的對象。「新項目」嚮導在建立該項目時爲你建立了兩個控制器。要看到它們,在「解決方案資源管理器」中展開Controllers文件夾。

HomeController 是傳統的ASP.NET MVC控制器。它負責對網站的HTML頁面進行服務,且與Web API無直接關係。

ValuesController 是一個例子型的WebAPI控制器。在下一步以前,將此控制器徹底刪除。

圖4.添加一個控制器

圖5.建立一個API控制器

修改此控制器的代碼以下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

using HelloWebAPI.Models;

namespace HelloWebAPI.Controllers
{
    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<Product> GetAllProducts()
        {
            return products;
        }
        public Product GetProductById(int id)
        {
            var product = products.FirstOrDefault((p) => p.Id == id);
            if (product == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            return product;
        }
        public IEnumerable<Product> GetProductsByCategory(string category)
        {
            return products.Where(
                (p) => string.Equals(p.Category, category,
                    StringComparison.OrdinalIgnoreCase));
        }
    }
}

 

爲了保持示例簡單,產品被存儲在該控制器類的一個固定數組中。固然,在一個實際應用程序中,你會查詢一個數據庫,或使用某些其它外部數據源。

該控制器定義了三個方法,它們或者返回一個單一產品,或一個產品列表:

GetAllProducts方法以IEnumerable<Product>類型返回產品的完整列表。

GetProductById方法經過ID查詢一個單一產品

GetProductsByCategory方法返回指定類別的所有產品。

好了,你有了一個能工做的Web API了。該控制器上的每一個方法都映射到一個URI(如表1所示):

 

表1. 控制器方法所映射的URI
Controller Method
控制器方法
URI
GetAllProducts /api/products
GetProductById /api/products/id
GetProductsByCategory /api/products/?category=category 

【調試】

 在VS中啓動調試。ASP.NET開發服務器(ASP.NET Development Server)將啓動,屏幕的右下角部將出現一個通知,顯示它運行的端口號。默認地,開發服務器選擇隨機端口號。

Visual Studio而後將自動打開瀏覽器窗口,其URL指向http//www.localhost:xxxx/,這裏,xxxx是端口號。首頁看上去應當像這樣(如圖6所示):

圖6.應用程序首頁

該首頁是一個ASP.NET MVC視圖,它是由HomeControllers類返回的。爲了調用Web API,咱們必須使用前面列出的URI之一。例如,要獲得所有產品列表,瀏覽http://localhost:xxxx/api/products/。

結果取決於你所使用的瀏覽器。Internet Explorer(IE瀏覽器)將提示你是否打開或保存一個名稱爲products的「文件」(如圖7所示)。

圖7.IE的提示

用記事本打開:

若是用Firefox或者Chrome訪問,則會在瀏覽器中用xml形式顯示:

 

出現這種差異的緣由是IE和Firefox發送了不一樣的Accept報頭,所以,Web API在響應中發送了不一樣的內容類型。

如今,試着瀏覽這些URI:

  • http://localhost:xxxx/api/products/1
  • http://localhost:xxxx/api/products?category=hardware

第一個應當返回ID等於1的詞條。第二個應當返回Category等於「hardware」的全部產品的列表(這裏,只有一個詞條)。

目前爲止就實現了一個最簡單的Web API應用。

有兩個改進的方向:

在IE上按「F12」啓動開發人員工具,能夠看見詳細的請求以及響應信息;

在頁面增長按鈕、輸入框等實現查詢等功能;

以上兩步詳見:調用與 Javascript 和 jQuery 的 Web API的最後部分;

 

【進階】

 一、實現CURD

CURD 是指對資源的增刪查改,對應了Create 、 Update 、 Read 、 Delete 四個簡單的數據庫操做。

在Web API中,Create 、 Update 、 Read 、 Delete 分別能夠經過Post,Put,Delete,Get四種HTTP方法來實現。固然,在實際應用中,更多的是使用了Get/Post方法。

在Web API中,默認在每一個方法名字以前加上Create 、 Update 、 Read 、 Delete字眼就能夠識別方法對應的HTTP方法,當讓,也能夠手動在每一個方法以前增長屬性標註,強制指明所使用的HTTP方法。以下所示:

[HttpGet]
        [ActionName("GetUser")]
        public IEnumerable<User> GetUsersByName(string userName)
        {
            return users.Where(
                (p) => string.Equals(p.UserName, userName,
                    StringComparison.OrdinalIgnoreCase));
        }

        [HttpPost]
        [ActionName("AddUser")]
        public User AddUser([FromBody]User user)
        {
            if (user == null)
            {
                throw new HttpRequestException();
            }
            users.Add(user);
            return user;
        }

至於ActionName標註,是方便在更改路由規則以後,能夠指定一個URL訪問的動做名字。

 

 二、API路由規則

 Web API會App_Start目錄的WebApiConfig.cs文件建立一個默認的路由模板是「api/{controller}/{id}」:

routes.MapHttpRoute( 
    name: "API Default", 
    routeTemplate: "api/{controller}/{id}", 
    defaults: new { id = RouteParameter.Optional } 
);

在這個模板中,「api」是一個標記式的文字路徑,而{controller}和{id}是佔位符變量。


當Web API接收到一個HTTP請求,它會試圖根據路由表中的一個路由模板來匹配其URI。若是無路由匹配,客戶端會接收到404(NotFound)錯誤。例如,如下URI與默認路由匹配:

  • /api/contacts
  • /api/contacts/1
  • /api/products/gizmo1

然而,如下URI不匹配,由於它缺乏「api」片斷:

  • /contacts/1

注:使用「api」的緣由是爲了不與ASP.NET MVC的路由衝突。經過這種方式,能夠用「/contacts」進入一個MVC控制器,而「/api/contacts」進入一個Web API控制器。

 

一旦匹配路由,Web API便會選擇相應的控制和動做:

1,根據URI中的「控制器」做爲{controller}變量的值找到Web API中的Controller。

2,爲了找到動做,Web API尋找一個名稱以HTTP方法名開頭的動做。例如,對於一個GET請求,Web API會查找一個以「Get…」開頭的動做,如「GetContact」或「GetAllContacts」等。這種約定僅運用於GET、POST、PUT和DELETE方法。經過把註解屬性運用於控制器,你能夠啓用其它HTTP方法。也可使用上述所說在每一個方法前增長屬性標註強制指明HTTP方法類型。

3,路由模板中的其它佔位變量,如{id},被映射成動做參數。

 

正如前文說,較多的HTTP請求使用Get/POST方法,這樣的話,就不排除在一個Controller裏面有好幾個POST方法而且參數格式也差很少的。因爲默認路由只會匹配第一個匹配的方法,因此僅僅是使用默認路由是知足不了要求的。

這種狀況下咱們能夠改變路由規則:

routes.MapHttpRoute( 
    name: "ActionApi", 
    routeTemplate: "api/{controller}/{action}/{id}", 
    defaults: new { id = RouteParameter.Optional } 
);

配合ActionName,NonAction標註,能夠更改更精準地匹配到方法。

public class ProductsController : ApiController 
{ 
    [HttpGet] 
    [ActionName("Thumbnail")] 
    public HttpResponseMessage GetThumbnailImage(int id); 

    [HttpPost] 
    [ActionName("Thumbnail")] 
    public void AddThumbnailImage(int id); 

    // Not an action method.
    // 不是一個動做方法
    [NonAction] 
    public string GetPrivateData() { ... }
}

 

 

 

【發佈】

 

【推薦網站】

ASP.NET Web API官方主頁

ASP.NET Web API系列教程目錄【對微軟官方主頁教程的良心翻譯】

我最喜好的功能:Entity Framework Code First和 ASP.NET Web API

相關文章
相關標籤/搜索