用ASP创建API。NET Core (Day2):在ASP中创建API。网络核心

时间:2024-12-24 08:04:19

表的内容 中间件路线图mvc模式介绍NET Core MVC中间件创建API控制器来返回ASP中的资源路由。净MVC核心 基于约定的路由属性的路由 通过路由返回资源处理模型类结论github上的源代码引用了其他系列 介绍 “用ASP实现Web API”系列文章。“NET Core”将专注于用ASP创建Web API。净的核心。在本系列的最后一篇文章中,我们学习了ASP。NET Core基础知识和如何建立一个空解决方案,并发挥与请求管道和中间件。在本文中,我们将讨论较少的理论,并尝试创建一个API。我们将使用ASP。NET Core MVC中间件,用于构建API。在本文中,我们将详细讨论如何返回资源、数据以及如何通过HTTP请求与API通信。我们可以使用在本系列最后一篇文章完成时获得的相同源代码。 中间件 要构建API,我们将在HTTP请求管道中添加中间件,我们可以通过在Startup类的Configure()方法中添加中间件来实现。为此,我们需要将服务添加到容器中。在。net的早期版本中,我们使用ASP中的Web API来构建服务。用于创建具有用户界面并由最终用户使用的应用程序,我们使用了asp.net。净MVC。当我们谈到ASP的时候。NET Core,我们现在没有一个独立的Web API框架。 MVC和Web API的功能现在合并在一个框架中。, ASP。网络核心MVC。其目的是构建使用api和MVC方法的web应用程序。要创建API,我们需要配置中间件并将其添加到请求管道中。 路线图 我们将按照路线图学习并涵盖ASP的所有方面。NET core详细说明。以下是将涵盖整个系列的路线图或文章列表: 用ASP创建API。NET Core(第1天):入门和ASP。NET Core请求管道用ASP创建API。NET Core(第二天):创建一个API并在ASP中返回资源。用asp.net core创建API。NET Core(第三天):在asp.net中使用HTTP状态码、序列化设置和内容协商。使用asp.net Core API创建API。NET Core(第4天):理解ASP中的资源。使用asp.net CORE API创建API。NET Core(第5天):asp.net中的控制反转和依赖注入。使用asp.net CORE API创建API。用asp.net Core(第6天):开始实体框架Core创建API。NET Core(第7天):asp.net中的实体框架核心。网络核心API MVC模式 MVC代表模型视图控制器。MVC基本上是一种用于定义用户界面的架构设计模式。它鼓励通过更好的可测试性实现松耦合和关注点分离。它由三部分组成。 模型负责业务逻辑。在某些情况下,当MVC模式仅在应用程序体系结构的顶层使用时,模型并不包含逻辑,而是由应用层(如业务层)的组件来处理它。在一些实现中,使用视图模型来检索和存储数据。视图是UI层,它负责以结构良好的格式和丰富的UI显示数据,例如以HTML的形式。控制器负责视图和模型之间的通信,并根据用户输入做出决策。就这些组件的依赖关系而言,控制器和视图依赖于模型,而控制器在某种程度上也依赖于视图。因此,控制器根据用户输入决定选择要显示给用户的视图,并在需要时将模型中的数据提供给视图。但当我们谈到构建API时,我们应该看看这个结构如何映射到我们的需求。在MVC术语中,视图基本上是我们作为响应获得的数据,也就是说,它以JSON的形式表示我们的资源或数据。 在我们的例子中,我们希望一个请求将来自任何其他用户应用程序有一个用户界面,只是想访问我们的服务,当请求时,将调用控制器的行为上,控制器将输入数据和模型返回到视图。在我们的例子中,视图不是aspx、razor或html页面,而是以JSON格式表示结果数据。 ASP。NET Core MVC中间件 现在我们将尝试添加ASP。NET Core MVC中间件到我们的应用程序。在startup类中,我们可以添加中间软件,但是要继续实现,首先要添加AspNetCore。MVC nugget包将应用程序作为服务定义在外部依赖名为Microsoft.AspNetCore。Mvc Nuget包。右键单击项目并选择“管理Nuget包”,如下所示。 现在安装Microsoft.AspNetCore的最新稳定版本。Mvc包。在我们的例子中,它是1.1.2。 一旦安装完毕,所有必需的与ASP相关的软件包都将被添加。净MVC。在Startup类中在ConfigureServices方法中,我们将向请求管道添加中间件。只需编写services.AddMVC()方法来添加服务。 隐藏,复制Code

// This method gets called by the runtime.
// Use this method to add services to the container.
// For more information on how to configure your application,
// visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}

在configure方法中,我们现在将把MVC中间件添加到请求管道中。在本例中,我们可以调用方法app.UseMvc();我们将在本系列第一篇文章中添加异常处理程序的位置之后添加这个。 因此,我们的异常处理程序在实际将请求委托给MVC中间件之前捕获异常,并处理与MVC相关的异常并发送正确的响应。我们现在还可以注释掉引入来引发异常的代码。 隐藏,复制Code

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(); if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler();
} app.UseMvc(); //app.Run(async (context) =>
//{
// throw new Exception("Test Dev Exception Page");
//}); //app.Run(async (context) =>
//{
// await context.Response.WriteAsync("Hello World!");
//});
}

导航到项目属性和调试选项卡,并将环境变量更改为Development(还记得吗?我们在上一篇文章中将其更改为生产模式)。 现在运行应用程序,我们得到一个空白页面。 现在按F12打开浏览器的开发者工具。我们仍然看到两个例外。 我们有404例外,即。,未找到状态。很明显,我们只是添加了MVC中间件,而没有做其他任何事情。没有返回数据的代码要执行,也没有定义路由。让我们创建一个控制器来返回数据或资源,比如员工信息。 创建API控制器来返回资源 现在我们将向应用程序添加一个新控制器,因为我们正在构建一个员工API,所以我们将控制器命名为EmployeesController。我们可以遵循基于模板的方法来添加具有默认动作方法的控制器,但从学习的角度来看,我们将从一个scratch实现开始,这样我们就可以真正知道我们正在创建什么,并且应该对代码有完全的控制。在项目中添加一个新文件夹并命名为Controllers,然后添加一个新类到那个Controllers文件夹并命名为EmployeesController。 EmployeesController应该派生自Microsoft.AspNetCore.Mvc。控制器类。 隐藏,复制Code

using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; namespace EmployeeInfo.API.Controllers
{
public class EmployeesInfoController : Controller
{
}
}

现在我们将添加负责返回数据的操作。因为我们需要以JSON格式返回数据,所以在这种情况下我们可以使用JsonResult类。这将把我们传递给JsonResult类构造函数的对象转换为JSON格式。 隐藏,复制Code

public JsonResult GetEmployees()
{
return new JsonResult();
}

由于我们需要返回雇员列表,理想情况下我们应该有一个雇员实体类,但是现在由于我们没有它,让我们创建三个匿名对象并返回雇员列表。 隐藏,复制Code

public JsonResult GetEmployees()
{
return new JsonResult(new List<object>()
{
new {employeeid = 01989, Name = "John Patrick"},
new {employeeid = 01987, Name= "Michael"},
new {employeeid = 01988, Name= "Akhil Mittal"}
});
}

当需要使用HTTP服务时,为了获取数据,我们需要向一个URI发送HTTP请求,该URI将请求委托给API的“Get”方法。我们可以从浏览器本身或任何工具发送请求,只是为了检查服务的响应。我们将使用邮差来进行所有这些请求和响应跟踪操作。 在Chrome浏览器应用程序中安装邮差并打开它。 所以,让我们打开邮差。在《邮差》中,我们可以提出自己的要求。首先运行应用程序,然后创建一个请求Uri以http://localhost:2542/api/employees获取雇员列表,选择GET方法并单击Send按钮发送请求。作为回应,我们没有得到员工列表,但状态为404未找到,如下图所示: 这意味着MVC框架到现在还不知道如何映射请求的URI。获取方法或GetEmployees方法的api/employee。下面是路由的概念。让我们详细探讨一下。 路由在ASP。净MVC核心 路由的目的是将Uri请求与控制器的特定方法相匹配。MVC框架负责解析接收到的请求,并将其映射到控制器和相应的操作。路由可以通过两种方式完成,第一种是基于约定的路由,第二种是基于属性的路由。 基于公约的路由 对于基于约定的路由,我们需要遵循如下约定: 隐藏,复制Code

app.UseMvc(config => {
config.MapRoute(
name: "Default",
template: "{controller}/{action}/{id?}",
defaults: new { controller = "Home", action = "Index" }
);
});

这与我们在。net的早期版本中使用的MVC或Web API类似。在本例中,我们需要在app.UseMvc方法中传递配置,以遵循基于约定的路由。这将把URI employees/索引映射到名为employees controller的控制器上的索引方法。这些是传统的路由方式,更适合典型的MVC应用程序,其中视图必须返回。对于基于API的应用程序,这种传统的基于路由不是首选和推荐的,而是推荐基于属性的路由。 基于属性的路由 基于属性的路由允许我们用我们想要的属性装饰我们的控制器和操作,因此给予路由操作更多的控制。模板提供这些属性,然后通过模板将Uri匹配到控制器的特定操作/方法。 最常见的功能API的lities是创建、读取、更新和删除操作。 为了读取资源,合适的HTTP方法是“GET”,所以在操作级的代码中,我们在负责读取和返回资源的代码上使用HttpGet属性。例如,api/employees将返回所有员工,而api/employees/01989将返回员工id为01989的员工。 POST是由HttpPost属性在操作级指定的。它负责创建资源或持久化资源。例如,api/employees Uri可用于创建员工资源。 PUT和PATCH用于更新uri,它们都在操作级别上使用。这两个Http方法之间有一个小的区别。当使用PUT时,它意味着它用于完全更新,即。,请求中的所有字段将覆盖现有字段,PUT的HTTP属性为HttpPut。对于PATCH,它是HttpPatch, PATCH意味着部分更新。与PUT不同的是,它不执行完全更新,而是局部更新,即。,如果我们使用补丁,很少字段也可以得到更新。 最后一个是DELETE, HTTP属性是HttpDelete。顾名思义,它用于删除uri,例如,api/employees/01989将删除id为01989的员工。 还有一个属性不映射到任何特定的HTTP属性,称为“Route”属性。此属性用于控制器级,以提供一个公共模板,并将其作为所有操作级属性的前缀。例如,如果我们知道我们的API URI从“API /employees”开始,Route属性可以在控制器级别使用,“API /employees”作为所有操作的模板值,因此我们可以跳过向所有操作提供这个特定的值。 通过路由返回资源 在前面的部分中,我们试图通过URI获取资源。现在我们知道了路由是如何工作的,所以只需将路由属性添加到动作中,看看它是如何工作的。因为我们需要获得雇员,所以我们将在操作上使用HttpGet属性。将[HttpGet(“api/employees”))放置在操作上。 隐藏,复制Code

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic; namespace EmployeeInfo.API.Controllers
{
public class EmployeesInfoController : Controller
{
[HttpGet("api/employees")]
public JsonResult GetEmployees()
{
return new JsonResult(new List<object>()
{
new {employeeid = 01989, Name = "John Patrick"},
new {employeeid = 01987, Name= "Michael"},
new {employeeid = 01988, Name= "Akhil Mittal"}
});
}
}
}

编译应用程序,运行它,然后再次通过URI从postman请求资源。 这一次,我们得到了预期的结果,即。,我们操作的员工列表。验证了路由和动作的有效性。那么我们现在有一个可用的API了? 控制器通常包含映射到CRUD操作的其他方法,我们希望我们的每个操作都有一个一致的URI。如果我们知道我们所有的动作都将“api/employees”作为属性,我们可以在控制器级使用Route属性,并在那里提供Uri的这一部分,如下所示: 隐藏,复制Code

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic; namespace EmployeeInfo.API.Controllers
{
[Route("api/employees")]
public class EmployeesInfoController : Controller
{
[HttpGet()]
public JsonResult GetEmployees()
{
return new JsonResult(new List<object>()
{
new {employeeid = 01989, Name = "John Patrick"},
new {employeeid = 01987, Name= "Michael"},
new {employeeid = 01988, Name= "Akhil Mittal"}
});
}
}
}

在本例中,默认情况下,当请求中包含Get Http谓词时,我们的Get方法将被调用并返回结果。运行应用程序并再次发送来自postman的请求来检查它是否工作。 在大多数情况下,我们将使用模型类、POCOs或dto,然后将它们序列化为JSON。现在我们来看看如何改进这个实现。 处理模型类 在本节中,我们将尽量避免直接返回JSON和匿名对象。因此,我们将为Employee创建一个模型/实体类。向项目添加一个名为Models的新文件夹,并添加一个名为EmployeeDto的类。向EmployeeDto类添加ID、名称、指定和薪水等属性。还可以将计算字段属性添加到DTO类中,例如,他过去工作过的公司的详细信息。 隐藏,复制Code

EmployeeDto Class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; namespace EmployeeInfo.API.Models
{
public class EmployeeDto
{
public int Id { get; set; }
public string Name { get; set; }
public string Designation { get; set; }
public string Salary { get; set; } public int NumberOfCompaniesWorkedWith { get; set; }
}
}

这里有一点很重要,即API返回或接受的内容与底层数据存储所使用的模型不同。现在,我们将使用内存中的数据,因为我们只关注API。因此,内存中的数据存储将简单地处理我们正在创建的这些DTO类。在本系列的后续文章中,我们将看到如何使用Entity Framework core处理数据库和对象。因为现在我们需要返回数据,所以我们将创建一个包含雇员列表的内存数据存储库。以后,我们总是可以使用数据库来获取数据,使用实体框架进行通信。 因此,添加一个名为EmployeesDataStore的新类并创建一个名为Employees的属性,即。,员工DTO列表。并添加一些虚拟数据。 在EmployeesDataStore上创建一个静态属性,并将其命名为Current,它将返回EmployeesDataStore的实例。由于它是静态属性,并且实例保留在内存中,所以我们可以继续处理类似的数据,直到再次启动应用程序为止。注意,这不是一个鼓励的方法,但我们暂时遵循它来理解主题。 EmployeesDataStore.cs: 隐藏,收缩,复制Code

using EmployeeInfo.API.Models;
using System.Collections.Generic; namespace EmployeeInfo.API
{
public class EmployeesDataStore
{
public static EmployeesDataStore Current { get; } = new EmployeesDataStore();
public List<employeedto> Employees { get; set; } public EmployeesDataStore()
{
//Dummy data
Employees = new List<employeedto>()
{
new EmployeeDto()
{
Id = 1,
Name = "Akhil Mittal",
Designation = "Technical Manager",
Salary="$50000"
},
new EmployeeDto()
{
Id = 2,
Name = "Keanu Reaves",
Designation = "Developer",
Salary="$20000"
},
new EmployeeDto()
{
Id = 3,
Name = "John Travolta",
Designation = "Senior Architect",
Salary="$70000"
},
new EmployeeDto()
{
Id = 4,
Name = "Brad Pitt",
Designation = "Program Manager",
Salary="$80000"
},
new EmployeeDto()
{
Id = 5,
Name = "Jason Statham",
Designation = "Delivery Head",
Salary="$90000"
}
};
}
}
}

现在我们可以转到控制器并修改实现。我们现在直接调用EmployeesData,而不是json列表中的匿名属性存储当前属性和那里的雇员。 隐藏,复制Code

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic; namespace EmployeeInfo.API.Controllers
{
[Route("api/employees")]
public class EmployeesInfoController : Controller
{
[HttpGet()]
public JsonResult GetEmployees()
{
return new JsonResult(EmployeesDataStore.Current.Employees);
}
}
}

现在运行应用程序,再次请求邮递员的响应。 因此,我们获得了在DataStore类中指定的所有员工的详细信息。 现在我们还可以创建新的操作,例如返回单个实体。添加一个名为GetEmployee的新操作,因为这也是一个Get,所以我们用HttpGet属性修饰它。URl应该是“api/employees”。,默认值+要获取的雇员的id [HttpGet("api/employees/{id}")],但由于"api/employees "是默认路由的一部分,我们可以跳过它,因为它将自动附加到动作路由。id是通过URI传递的参数,它也必须是操作的参数,以便获取具有id的所需员工。 隐藏,复制Code

[HttpGet("{id}")]
public JsonResult GetEmployee(int id)
{
return new JsonResult
(EmployeesDataStore.Current.Employees.FirstOrDefault(emp => emp.Id == id));
}

在上面的操作方法中,我们从雇员数据存储列表中找到其id与传递的id参数匹配的特定雇员。现在编译项目。运行应用程序并从postman那里发出GET请求,但是现在使用不同的URI,即。http://localhost: 2542 / api /员工/ 1。 与http://localhost: 2542 / api /员工/ 2: 因此,我们从员工列表中只获得一个员工,并且通过URI传递该员工的id为1。因此,路由模板匹配到操作的正确路由,然后调用操作。 现在设想一个场景,您使用不存在的路由或员工触发请求,例如http://localhost:2542/api/companies,我们得到以下404响应,即。,没有被发现,这很好。 如果我们记得以前的实现,我们有500个内部服务器错误。这些代码基本上是HTTP状态代码在这里,框架会自动返回。 如果我们尝试获得一个不存在的雇员,例如http://localhost:2542/api/employee/8,我们会得到200个结果为空的OK结果。 框架本身不会返回404,因为我们的URI可以被路由。但是返回null是不正确的结果。因此,如果该员工不存在,我们也应该从代码或API获得404响应。在任何情况下,我们都应该返回正确的状态码。在本系列的下一篇文章中,我们将讨论状态代码以及更多内容。请继续关注吗? 结论 在这篇文章中,我们了解了MVC模式,以及传统的Web API和MVC与我们在ASP中所拥有的有何不同。网络核心MVC。我们从了解什么是MVC模式开始,即模型-视图-控制器。模型负责应用程序数据的业务逻辑。视图表示显示数据的区域,在API中,数据通常是API返回的JSON格式,控制器处理视图和模型之间的通信。这种模式使我们能够编写可重用和可测试的代码。我们学习了如何添加MVC中间件,以及如何使用HttpGet从API中获取数据。我们了解了路由如何处理请求uri并映射到控制器的操作。我们学习了如何从头创建API,以及如何处理实体对象和返回资源。在下一篇文章中,我们将讨论HTTP状态码、返回子资源、序列化字符串和内容协商等主题。 ,,,,,& lt;才能& lt;前一篇文章,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,下一篇文章在祝辞 Github上的源代码 下载源代码 参考文献 https://www.asp.net/core https://www.pluralsight.com/courses/asp-dotnet-core-api-building-first|0>>>> 其他系列 我的系列文章如下: 在。net中学习webapi,在Visual Studio 2015中学习Visual Studio的可扩展性 本文转载于:http://www.diyabc.com/frontweb/news18173.html