现在的位置: 主页 > 公司荣誉 > 文章列表

ASP.NET 5系列教程(七)完结篇-解读代码

作者:成都金海力科技有限公司 来源:www.scjinhaili.com 未知发布时间:2017-09-12 15:40:40
ASP.NET 5系列教程(七)完结篇-解读代码

在本文中,我们将一起查看TodoController 类代码。

[Route] 属性定义了Controller的URL 模板:

[Route(api/[controller])]

所有符合该模板类型的HTTP 请求都会被路由到该controller。在本例中, 路由的命名规范为对应Controller 的前缀,对于TodoController 类,路由模板为 “api/todo”。

HTTP 方法

[HttpGet]、[HttpPost]和[HttpDelete] 属性定义为 controller 动作对应的HTTP 方法 (另外也有[HttpPut] 和 [HttpPatch] 属性,在本示例中没有使用。)

[HttpGet] public IEnumerable GetAll() {} [HttpGet({id:int}, Name = GetByIdRoute)] public IActionResult GetById (int id) {} [HttpPost] public void CreateTodoItem([FromBody] TodoItem item) {} [HttpDelete({id:int})] public 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

不能写为:

http://localhost/api/todo/abc

注意 GetById 和 DeleteItem 方法同样拥有命名为id的参数。framework 会自动传递实参值到Controller中。例如,如果URL为http://localhost/api/todo/42,id的值则为42,这个过程为参数绑定。

CreateTodoItem 方法代表了另一个参数绑定:

[HttpPost] public 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] public IEnumerable GetAll() { return _items; }

返回对象的序列化信息被存储到Response消息中。默认格式为JSON,客户端同样可以接收XML数据格式:

GET 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 Date: Thu, 30 Oct 2014 22:40:10 GMT Content-Length: 228 1false

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

[HttpGet({id:int}, Name = GetByIdRoute)] public IActionResult GetById (int id) { var item = _items.FirstOrDefault(x => x.Id == id); if (item == null) { return HttpNotFound(); } return new ObjectResult(item); }

如果有URL中对应的id,则这个方法会返回ObjectResult 。返回 ObjectResult 和返回CLR 模型相同。而方法中规定返回类型为IActionResult。因此,该方法可以返回不同的类型。

如果没有对应ID,则返回HttpNotFound,页面会抛出404 错误。

最后,采集软件, CreateTodoItem 方法展示如何直接在方法中设置返回值:

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

这种方法的缺陷是很难进行单元测试。(关于测试相关讨论,可以参考Unit Testing Controllers in ASP.NET Web API)。

依赖注入

MVC 6 内置了依赖注入功能。下面,让我们创建一个包含ToDo列表的repository 类。

首先,为repository定义一个接口:

using System.Collections.Generic; namespace TodoApi.Models { public interface ITodoRepository { IEnumerable AllItems { get; } void Add(TodoItem item); TodoItem GetById(int id); bool TryDelete(int id); } }

之后定义具体实现方法。

using System; using System.Collections.Generic; using System.Linq; namespace TodoApi.Models { public class TodoRepository : ITodoRepository { readonly List _items = new List(); public IEnumerable AllItems { get { return _items; } } public TodoItem GetById(int id) { return _items.FirstOrDefault(x => x.Id == id); } public void Add(TodoItem item) { item.Id = 1 + _items.Max(x => (int?)x.Id) ?? 0; _items.Add(item); } public bool TryDelete(int id) { var item = GetById(id); if (item == null) { return false; } _items.Remove(item); return true; } } }

使用构造函数注入repository 到 controller:

[Route(api/[controller])] public class TodoController : Controller { // Remove this code: //static readonly List _items = new List() //{ // new TodoItem { Id = 1, Title = First Item } //}; // Add this code: private readonly ITodoRepository _repository; public TodoController(ITodoRepository repository) { _repository = repository; }

然后更新controller 方法到repository:

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

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:天门网站建设 http://tianmen.45qun.com

上一篇:Farseer.net轻量级开源框架 中级篇:DbFactory数据工 下一篇:最后一页