0. 项目结构
在创建ASP.NET Core Web API项目后,项目的基本结构如下:
MyWebApiProject
│ Controllers
│ └── WeatherForecastController.cs
│ Program.cs
│ WeatherForecast.cs
│ appsettings.json
│ ...
1. Program.cs
这个文件是应用程序的入口点,负责配置和启动Web服务器。
var builder = WebApplication.CreateBuilder(args);
-
WebApplication.CreateBuilder(args)
:创建一个Web应用程序构建器。 -
args
:命令行参数。builder.Services.AddControllers();
-
builder.Services
:表示依赖注入容器。 -
AddControllers
:向依赖注入容器添加控制器服务。builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
-
AddEndpointsApiExplorer
:用于API文档生成。 -
AddSwaggerGen
:添加Swagger生成器,生成API文档。var app = builder.Build();
-
builder.Build()
:构建Web应用程序。if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI();
}
-
app.Environment.IsDevelopment()
:检查当前环境是否是开发环境。 -
UseDeveloperExceptionPage
:在开发环境中使用开发者异常页面。 -
UseSwagger
和UseSwaggerUI
:启用Swagger中间件,提供API文档UI。app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
-
UseHttpsRedirection
:强制使用HTTPS。 -
UseAuthorization
:启用授权中间件。 -
MapControllers
:将控制器映射到路由。 -
app.Run()
:运行Web应用程序。
2. WeatherForecast.cs
这个文件定义了天气预报的数据模型。
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}
Date
:表示预报的日期。TemperatureC
:表示摄氏温度。TemperatureF
:表示华氏温度,通过摄氏温度计算得出。Summary
:表示天气总结,可以为空(string?
表示可空类型)。
3. WeatherForecastController.cs
这个文件定义了一个控制器类,处理与天气预报相关的HTTP请求。
using Microsoft.AspNetCore.Mvc;
-
using
语句:导入命名空间,包含Microsoft.AspNetCore.Mvc
用于控制器相关功能。namespace MyWebApiProject.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger; public WeatherForecastController(ILogger<WeatherForecastController> logger) { _logger = logger; } [HttpGet] public IEnumerable<WeatherForecast> Get() { var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray(); } }
}
详细解析:
-
[ApiController]
- 标记该类为API控制器,启用一些自动化功能,如模型验证和路由推断。
-
[Route("[controller]")]
- 定义控制器的路由模板。
[controller]
占位符会被控制器名称替换(去掉"Controller"后缀)。
- 定义控制器的路由模板。
-
控制器类:
public class WeatherForecastController : ControllerBase
WeatherForecastController
:控制器类,继承自ControllerBase
。ControllerBase
:提供访问控制器功能的基类,不包含视图支持。
-
Summaries
字段:private static readonly string[] Summaries = new[]
- 定义了一个静态只读数组,包含各种天气总结描述。
-
构造函数:
public WeatherForecastController(ILogger<WeatherForecastController> logger)
- 依赖注入
ILogger<WeatherForecastController>
实例,用于日志记录。
- 依赖注入
-
Get
方法:[HttpGet] public IEnumerable<WeatherForecast> Get()
-
[HttpGet]
:标记该方法处理HTTP GET请求。 -
Get
方法返回一个IEnumerable<WeatherForecast>
,生成并返回5天的天气预报数据。var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
-
创建一个随机数生成器。
-
使用
Enumerable.Range
生成1到5的整数序列。 -
使用
Select
方法将每个整数转换为一个WeatherForecast
对象。 -
生成日期为当前日期加上序列中的天数。
-
生成随机的摄氏温度和天气总结。
-
将结果转换为数组并返回。
-
设计代码结构的建议
在ASP.NET Core Web API项目中,将代码分为模型层、控制器层、服务层和数据访问层有助于组织代码,使其更易于维护和扩展。以下是各个层的详细描述以及它们存放的代码类型:
1. 模型层(Models)
模型层存放数据结构和业务对象,这些对象通常反映了系统的核心业务实体。
- 数据模型:表示数据的结构,如数据库表的实体。
- 数据传输对象(DTO):用于在客户端和服务器之间传输数据。
- 视图模型:用于将数据从控制器传递到视图(在API中较少使用)。
示例:
// 文件路径:Models/WeatherForecast.cs
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}
2. 控制器层(Controllers)
控制器层包含控制器类,这些类处理HTTP请求并返回响应。控制器通常使用服务层来处理业务逻辑。
- 控制器:处理HTTP请求,调用服务层,并返回响应。
- 属性和方法:处理特定的HTTP请求(如GET、POST、PUT、DELETE)。
示例:
// 文件路径:Controllers/WeatherForecastController.cs
using Microsoft.AspNetCore.Mvc;
using MyWebApiProject.Services;
namespace MyWebApiProject.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private readonly IWeatherForecastService _weatherForecastService;
public WeatherForecastController(IWeatherForecastService weatherForecastService)
{
_weatherForecastService = weatherForecastService;
}
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
return _weatherForecastService.GetWeatherForecasts();
}
}
}
3. 服务层(Services)
服务层包含业务逻辑和操作,这些逻辑通常涉及多个数据模型或需要复杂的业务规则。服务层从数据访问层获取数据并进行处理。
- 服务接口:定义服务的合同。
- 服务实现:实现服务接口,包含具体的业务逻辑。
示例:
// 文件路径:Services/IWeatherForecastService.cs
using MyWebApiProject.Models;
public interface IWeatherForecastService
{
IEnumerable<WeatherForecast> GetWeatherForecasts();
}
// 文件路径:Services/WeatherForecastService.cs
using MyWebApiProject.Models;
using MyWebApiProject.Data;
public class WeatherForecastService : IWeatherForecastService
{
private readonly IWeatherForecastRepository _repository;
public WeatherForecastService(IWeatherForecastRepository repository)
{
_repository = repository;
}
public IEnumerable<WeatherForecast> GetWeatherForecasts()
{
return _repository.GetWeatherForecasts();
}
}
4. 数据访问层(Data Access Layer, DAL)
数据访问层处理与数据库的交互,负责从数据库中检索和存储数据。
- 仓储接口:定义数据访问的合同。
- 仓储实现:实现仓储接口,包含具体的数据访问逻辑。
- 数据上下文:表示数据库连接和操作。
示例:
// 文件路径:Data/IWeatherForecastRepository.cs
using MyWebApiProject.Models;
public interface IWeatherForecastRepository
{
IEnumerable<WeatherForecast> GetWeatherForecasts();
}
// 文件路径:Data/WeatherForecastRepository.cs
using MyWebApiProject.Models;
using System.Collections.Generic;
public class WeatherForecastRepository : IWeatherForecastRepository
{
public IEnumerable<WeatherForecast> GetWeatherForecasts()
{
// 这里可以连接数据库并获取数据
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
}
代码结构设计建议
以下是一个示例项目的目录结构,以帮助组织各个层的代码:
MyWebApiProject
│
├── Controllers
│ └── WeatherForecastController.cs
│
├── Models
│ └── WeatherForecast.cs
│
├── Services
│ ├── IWeatherForecastService.cs
│ └── WeatherForecastService.cs
│
├── Data
│ ├── IWeatherForecastRepository.cs
│ └── WeatherForecastRepository.cs
│
├── Program.cs
├── Startup.cs (如果使用Startup类进行配置)
├── appsettings.json
│
└── MyWebApiProject.csproj
各层的实现原理
- 模型层:定义应用程序的数据结构,表示业务实体和数据传输对象。
- 控制器层:处理HTTP请求,通过调用服务层获取或处理数据,然后返回HTTP响应。
- 服务层:包含业务逻辑,处理复杂的操作和业务规则。通过调用数据访问层获取和存储数据。
- 数据访问层:与数据库或其他数据源交互,执行CRUD(创建、读取、更新、删除)操作,返回数据给服务层。
通过这种分层结构,可以使代码更加模块化、易于维护和测试,同时清晰地分离了各个部分的职责。