ASP.NET 4.x Web API 是一种 HTTP 服务,它可到达各种客户端,包括浏览器和移动设备。 ASP.NET Core 将 ASP.NET 4.x 的 MVC 和 Web API 应用模型组合到被称为 ASP.NET Core MVC 的单一编程模型中。 本文演示从 ASP.NET 4.x Web API 迁移到 ASP.NET Core MVC 所需的步骤。
先决条件
- 具有“ASP.NET 和 Web 开发”工作负载的 Visual Studio 2019 16.4 或更高版本
- .NET Core 3.1 SDK
查看 ASP.NET 4.x Web API 项目
本文使用在 ASP.NET Web API 2 入门中创建的 ProductsApp 项目。 在该项目中,按如下方式配置基本 ASP.NET 4.x Web API 项目。
在 Global.asax.cs 中,对 执行调用:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Routing;
namespace ProductsApp
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
}
}
}
WebApiConfig
类位于 App_Start 文件夹中,具有一个静态 Register
方法:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace ProductsApp
{
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 }
);
}
}
}
上述类会执行以下操作:
- 配置属性路由(虽然实际上并没有使用它)。
- 配置路由表。 示例代码要求 URL 匹配格式
/api/{controller}/{id}
,其中{id}
是可选的。
以下部分演示了如何将 Web API 项目迁移到 ASP.NET Core MVC。
创建目标项目
在 Visual Studio 中创建新的空白解决方案,并添加 ASP.NET 4.x Web API 项目进行迁移:
- 从“文件”菜单中选择“新建”“项目”。
- 选择“空白解决方案”模板,然后选择“下一步”。
- 将解决方案命名为 WebAPIMigration。 选择“创建”。
- 将现有的 ProductsApp 项目添加到解决方案。
添加要迁移到的新 API 项目:
- 将新的“ASP.NET Core Web 应用程序”项目添加到解决方案中。
- 在“配置新项目”对话框中,将项目命名为 ProductsCore,然后选择“创建”。
- 在“创建新的 ASP.NET Core Web 应用程序”对话框中,确认选择“.NET Core”和“ASP.NET Core 3.1” 。 选择“API”项目模板,然后选择“创建” 。
- 从新的 ProductsCore 项目中删除 WeatherForecast.cs 和 Controllers/WeatherForecastController.cs 示例文件。
解决方案包含两个项目。 以下部分介绍了如何将 ProductsApp 项目的内容迁移到 ProductsCore 项目。
迁移配置
ASP.NET Core 不使用 App_Start 文件夹或 Global.asax 文件。 此外,还会在发布时添加 web.config 文件。
Startup
类:
- 替换 Global.asax。
- 处理所有应用启动任务。
迁移模型和控制器
下面的代码演示了要为 ASP.NET Core 更新的 ProductsController
:
using ProductsApp.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;
namespace ProductsApp.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 IHttpActionResult GetProduct(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
}
}
更新 ASP.NET Core 的 ProductsController
:
- 将 Controllers/ProductsController.cs 和 Models 文件夹从原始项目复制到新项目。
- 将复制的文件的根命名空间更改为
ProductsCore
。 - 将
using ProductsApp.Models;
语句更新为using ProductsCore.Models;
。
ASP.NET Core 中不存在下列组件:
ApiController
类System.Web.Http
命名空间IHttpActionResult
接口
进行以下更改:
- 将
ApiController
更改为 ControllerBase。 添加using Microsoft.AspNetCore.Mvc;
来解析ControllerBase
引用。 - 删除
using System.Web.Http;
。 - 将
GetProduct
操作的返回类型从IHttpActionResult
更改为ActionResult<Product>
。 - 将
GetProduct
操作的return
语句简化为如下内容:C#复制return product;
配置路由
ASP.NET Core API 项目模板在生成的代码中包含终结点路由配置。
以下 UseRouting 和 UseEndpoints 调用会执行以下操作:
- 在中间件管道中注册路由匹配和终结点执行。
- 替换 ProductsApp 项目的 App_Start/WebApiConfig.cs 文件。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
按如下所示配置路由:
- 使用以下属性标记
ProductsController
类:C#复制[Route("api/[controller]")] [ApiController]
上述[Route]
属性会配置控制器的属性路由模式。[ApiController]
属性使得此控制器中所有操作都必须使用属性路由。属性路由支持标记,例如[controller]
和[action]
。 在运行时,每个标记分别替换为应用了属性的控制器或操作的名称。 令牌执行以下操作:- 减少项目中的魔幻字符串的数量。
- 应用自动重命名重构时,请确保路由与相应的控制器和操作保持同步。
- 启用对
ProductController
操作的 HTTP Get 请求:- 将
[HttpGet]
属性应用于GetAllProducts
操作。 - 将
[HttpGet("{id}")]
属性应用于GetProduct
操作。
- 将
运行迁移的项目,并浏览到 /api/products
。 这会显示包含三个产品的完整列表。 浏览到 /api/products/1
。 此时显示第一个产品。