.Net6中遵循MVC Architecture开发后端选Asp.Net Web Api还是Asp.Net MVC?
从.NET Core 1.0版本发布至今(包含你使用的.NET6),.NET Framework时代分立的ASP.NET MVC和ASP.NET Web API已经完成技术栈合并,不存在二选一的问题。
注意:只有在已停止官方更新的.NET Framework 4.x版本中,ASP.NET MVC和ASP.NET Web API才是两套独立并行的技术:前者主要用于构建返回HTML视图的服务端渲染网页,后者专门用于构建REST风格接口,二者管线、路由逻辑多有重复,因此微软在.NET Core时代直接将二者合并为统一的MVC中间件核心。
如果你要做纯后端接口服务,直接选择ASP.NET Core Web API模板即可,它原生完整支持MVC架构规范,不需要额外做适配。如果误选带Razor视图的MVC模板,反而会默认引入一堆视图渲染相关的冗余依赖,不适合纯接口场景。
MVC架构的核心是职责拆分:
- Model:负责封装业务数据、实现业务逻辑规则、处理数据读写
- View:负责展示层内容渲染
- Controller:负责接收用户请求、协调Model层完成处理、返回最终响应结果
ASP.NET Core Web API的原生管线完全贴合这个拆分逻辑:Controller基类、模型绑定、模型校验、结果格式化这些核心组件都和MVC能力完全共用。纯接口场景下,View层不需要返回HTML内容,直接替换为框架默认的JSON/XML序列化输出逻辑即可,完全不违背MVC的核心设计原则。
1. 项目初始化
在命令行执行以下指令创建基础Web API项目,模板默认集成MVC核心依赖,不需要额外安装Nuget包:
dotnet new webapi -n MvcWebApiDemo cd MvcWebApiDemo
2. 按MVC职责边界搭建目录结构
在项目根目录创建对应分层目录,严格遵守职责隔离原则:
Controllers:模板默认生成,仅存放接口入口类,禁止在Controller中编写任何业务逻辑,Controller只做三件事:接收校验请求参数、调用Model层业务方法、将处理结果封装为HTTP响应返回Models:手动创建该目录,作为Model层的根目录,可根据业务复杂度再做细分:Dtos:存放接口传输用的数据模型,包括请求入参类、响应出参类Entities:存放数据库映射的实体类Services:存放业务逻辑实现类,复杂场景可继续拆分仓储层、领域层模块,所有业务规则全部收敛在该目录下
3. 代码实现示例
以用户信息查询接口为例:
首先在Models/Dtos目录下创建传输模型UserDto.cs:
namespace MvcWebApiDemo.Models.Dtos { public class UserDto { public int Id { get; set; } public string Name { get; set; } = string.Empty; public DateTime CreateTime { get; set; } } }
然后在Models/Services目录下创建业务逻辑类UserService.cs(属于Model层):
using MvcWebApiDemo.Models.Dtos; namespace MvcWebApiDemo.Models.Services { public class UserService { // 模拟用户数据查询逻辑,实际场景可替换为数据库访问操作 public UserDto? GetUserById(int userId) { if (userId <= 0) return null; return new UserDto { Id = userId, Name = "DefaultUser", CreateTime = DateTime.Now }; } } }
最后在Controllers目录下创建接口入口UsersController.cs:
using Microsoft.AspNetCore.Mvc; using MvcWebApiDemo.Models.Dtos; using MvcWebApiDemo.Models.Services; namespace MvcWebApiDemo.Controllers { [Route("api/[controller]")] [ApiController] public class UsersController : ControllerBase { private readonly UserService _userService; // 依赖注入Model层的业务服务 public UsersController(UserService userService) { _userService = userService; } [HttpGet("{id}")] public ActionResult<UserDto> GetUserById(int id) { var userInfo = _userService.GetUserById(id); return userInfo == null ? NotFound() : Ok(userInfo); } } }
4. 服务与中间件配置
打开项目根目录的Program.cs,注册MVC服务和业务服务,配置核心中间件:
var builder = WebApplication.CreateBuilder(args); // 注册MVC核心控制器服务,Web API模板默认已添加该配置 builder.Services.AddControllers(); // 注册Model层的业务服务,根据场景选择Scoped/Transient/Singleton生命周期 builder.Services.AddScoped<UserService>(); var app = builder.Build(); // 配置HTTP请求管线 app.UseHttpsRedirection(); app.UseAuthorization(); // 映射Controller路由,是MVC请求处理的核心入口配置 app.MapControllers(); app.Run();
执行dotnet run启动项目后,访问/api/users/1即可拿到正确的接口响应。
架构注意事项
- 严格守住职责边界:不要在Controller中写数据访问、业务计算、参数复杂加工的逻辑,所有业务规则必须收敛到Model层,避免后续维护时代码混乱
- 纯接口场景不需要引入Razor视图引擎相关能力,不会产生额外的性能开销
- 后续如果需要新增服务端渲染网页的能力,直接在项目中添加View目录、启用Razor配置即可,不需要切换技术栈。
内容的提问来源于stack exchange,提问作者Zameer Ahammad

