ASP.NET 5系列教程(七)完結篇-解讀代碼

在本文中,咱們將一塊兒查看TodoController 類代碼。html

[Route] 屬性定義了Controller的URL 模板:web

[Route("")]

 

全部符合該模板類型的HTTP 請求都會被路由到該controller。在本例中, 路由的命名規範爲對應Controller 的前綴,對於TodoController 類,路由模板爲 「api/todo」。json

HTTP 方法api

[HttpGet][HttpPost][HttpDelete] 屬性定義爲 controller 動做對應的HTTP 方法 (另外也有[HttpPut][HttpPatch] 屬性,在本示例中沒有使用。)瀏覽器

[HttpGet]
 IEnumerable<TodoItem> GetAll() {}
 
[HttpGet("", Name = "")]
 IActionResult GetById (int id) {}
 
[HttpPost]
 void CreateTodoItem([FromBody] TodoItem item) {}
 
[HttpDelete("")]
 IActionResult DeleteItem(int id) {}

 

GetById 和DeleteItem 方法中的參數能夠增長路由的傳遞信息。因此,路由模板更加完善的寫法爲「api/[controller]/{id:int}」。安全

在 「{id:int}」 中,id是變量,而 「:int」 表明參數爲整型。如下爲URLs實例:服務器

http://localhost/api/todo/1
http://localhost/api/todo/42

不能寫爲:mvc

http://localhost/api/todo/abc

 

注意 GetById 和 DeleteItem 方法一樣擁有命名爲id的參數。framework 會自動傳遞實參值到Controller中。例如,若是URL爲http://localhost/api/todo/42,id的值則爲42,這個過程爲參數綁定。app

CreateTodoItem 方法表明了另外一個參數綁定:asp.net

[HttpPost]
 void CreateTodoItem([FromBody] TodoItem item) {}

 

[FromBody] 屬性指定framework 從Request中反序列化TodoItem 參數。

如下是request和controller 動做的對應列表:

Request

Controller Action

GET /api/todo

GetAll

POST /api/todo

CreateTodoItem

GET /api/todo/1

GetById

DELETE /api/todo/1

DeleteItem

GET /api/todo/abc

none – returns 404

PUT /api/todo

none – returns 404

最後兩個例子因爲其餘用途返回404 錯誤。例如 'GET /api/todo/abc', 'abc' 實參是GetById 方法中要求的整型數據類型。

Action 返回值

TodoController 類展現了多種 controller action的返回值方法。

GetAll 方法返回了一個CLR 對象。

[HttpGet]
 IEnumerable<TodoItem> GetAll()
{
     _items;
}

返回對象的序列化信息被存儲到Response消息中。默認格式爲JSON,客戶端一樣能夠接收XML數據格式:

 http://localhost:5000/api/todo HTTP/1.1
 
User-Agent: Fiddler
 
Host: localhost:5000
 
Accept: application/xml

Response:

HTTP/1.1 200 OK
Content-Type: application/xml;charset=utf-8
Server: Microsoft-HTTPAPI/2.0
: Thu, 30 Oct 2014 22:40:10 GMT
Content-Length: 228
 
<ArrayOfTodoItem xmlns:i="" xmlns=""><TodoItem><Id>1</Id><IsDone></IsDone><Title>First Item</Title></TodoItem></ArrayOfTodoItem>

 

GetById 方法返回了一個IActionResult 接口:

[HttpGet("", Name = "")]
 IActionResult GetById (int id)
{
    var item = _items.FirstOrDefault(x => x.Id == id);
     (item == null)
    {
         HttpNotFound();
    }
 
      ObjectResult(item);
}

 

若是有URL中對應的id,則這個方法會返回ObjectResult 。返回 ObjectResult 和返回CLR 模型相同。而方法中規定返回類型爲IActionResult。所以,該方法能夠返回不一樣的類型。

若是沒有對應ID,則返回HttpNotFound,頁面會拋出404 錯誤。

最後, CreateTodoItem 方法展現如何直接在方法中設置返回值:

[HttpPost]
 void CreateTodoItem([FromBody] TodoItem item)
{
    // (some code  shown here)
 
    Context.Response.StatusCode = 201;
    Context.Response.Headers[""] = url;
}

 

這種方法的缺陷是很難進行單元測試。(關於測試相關討論,能夠參考Unit Testing Controllers in ASP.NET Web API)。

依賴注入

MVC 6 內置了依賴注入功能。下面,讓咱們建立一個包含ToDo列表的repository 類。

首先,爲repository定義一個接口:

 System.Collections.Generic;
 
 TodoApi.Models
{
      ITodoRepository
    {
        IEnumerable<TodoItem> AllItems { ; }
        void Add(TodoItem item);
        TodoItem GetById(int id);
        bool TryDelete(int id);
    }
}

 

以後定義具體實現方法。

 System;
 System.Collections.Generic;
 System.Linq;
 
 TodoApi.Models
{
      TodoRepository : ITodoRepository
    {
         List<TodoItem> _items =  List<TodoItem>();
 
         IEnumerable<TodoItem> AllItems
        {
get
            {
                 _items;
            }
        }
 
         TodoItem GetById(int id)
        {
             _items.FirstOrDefault(x => x.Id == id);
        }
 
         void Add(TodoItem item)
        {
            item.Id = 1 + _items.Max(x => (int?)x.Id) ?? 0;
            _items.Add(item);
        }
 
         bool TryDelete(int id)
        {
            var item = GetById(id);
             (item == null)
            {
                 ;
            }
            _items.Remove(item);
             ;
        }
    }
}

 

使用構造函數注入repository 到 controller:

[Route("")]
  TodoController : Controller
{
    // Remove this code:
    //  List<TodoItem> _items =  List<TodoItem>()
    //{
    //     TodoItem { Id = 1, Title = "" }
    //};
 
    // Add this code:
      ITodoRepository _repository;
 
     TodoController(ITodoRepository repository)
    {
        _repository = repository;
    }

 

而後更新controller 方法到repository:

[HttpGet]
 IEnumerable<TodoItem> GetAll()
{
     _repository.AllItems;
}
[HttpGet("", Name = "")]
 IActionResult GetById(int id)
{
    var item = _repository.GetById(id);
     (item == null)
    {
         HttpNotFound();
    }
 
      ObjectResult(item);
}
 
[HttpPost]
 void CreateTodoItem([FromBody] TodoItem item)
{
     (!ModelState.IsValid)
    {
        Context.Response.StatusCode = 400;
    }
else
    {
        _repository.Add(item);
 
         url = Url.RouteUrl("",  { id = item.Id }, Request.Scheme, Request.Host.ToUriComponent());
        Context.Response.StatusCode = 201;
        Context.Response.Headers[""] = url;
    }
}
 
[HttpDelete("")]
 IActionResult DeleteItem(int id)
{
     (_repository.TryDelete(id))
    {
          HttpStatusCodeResult(204); // 201 No Content
    }
else
    {
         HttpNotFound();
    }
}

 

咱們須要註冊repository到依賴注入系統才能使其啓做用。在Startup 類中,添加如下代碼:

 void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    //  code
    services.AddSingleton<ITodoRepository, TodoRepository>();
}

 

應用運行時, 一旦controller被建立,framework 自動注入TodoRepository 到controller中,它將做用於整個應用的生命週期。

在IIS外獨立部署應用

默認狀況下,當你點擊F5,應用會在IIS Express中運行。你能夠在工具欄中看到IIS Express 圖標。

clip_image001

 

ASP.NET 5.0 能夠部署到不一樣的服務器中,在本節中,咱們將使用可運行在IIS外的WebListener。

注意:將應用部署在IIS中仍有諸多的優點,例如安全性、進度管理等。

在project.json 文件,添加Microsoft.AspNet.Server.WebListener 包:

"": {
    "": "",
    "": "",
    "": "",
// New:
    "": ""
},

 

接下來添加如下選項到project.json。

{
// Other sections not shown
 
    "": {
        "": ""
    }
}

 

「commands」 中包含了能夠傳遞給K 運行時的預約義指令列表。在這個例子中, 「web」 是指令名稱,它能夠是任意實際指令名稱值。

Microsoft.AspNet.Hosting 程序集用於部署ASP.NET 5.0 應用。

· --server 標記用於聲明服務器,在這個例子中爲WebListener。

· --server.urls 標記提供須要監聽的URL。

保存project.json 文件。在Solution Explorer中,右鍵點擊工程選擇Properties。在 Properties 欄,點擊Debug。在Debug target 下,更改 「IIS Express」 爲 「web」。

clip_image001[5]

 

點擊F5運行App。Visual Studio 這時會運行啓動WebListener 的控制檯應用。

clip_image001[7]

打開瀏覽器,輸入http://localhost:5000。你能夠看到歡迎界面。

若是須要使用IIS,在上一步驟中更改Debug Target 爲 「IIS Express」便可。

這篇文章爲本系列文章的最後一篇,感謝你們的關注。本系列的全部教程旨在幫助你們更好的理解ASP.NET 5,以便更好的進行開發。同時,也能夠藉助一些開發工具來助力開發過程。ComponentOne Studio for ASP.NET 是ASP.NET平臺上的一整套完備的開發工具包,用於在各類瀏覽器中建立和設計具備現代風格的Web應用程序。

這篇文章爲本系列文章的最後一篇,感謝你們的關注。

原文連接:http://www.asp.net/vnext/overview/aspnet-vnext/create-a-web-api-with-mvc-6

 

目錄:

相關文章
相關標籤/搜索