C#中創(chuàng)建統(tǒng)一API接口的實(shí)現(xiàn)方案
一、技術(shù)選型與架構(gòu)設(shè)計(jì)
框架選擇
- ASP.NET Core (6.0+)
- RESTful API 規(guī)范
核心組件
- 統(tǒng)一響應(yīng)格式:標(biāo)準(zhǔn)化 JSON 響應(yīng)結(jié)構(gòu)
- 全局異常處理:統(tǒng)一錯誤返回
- 版本控制:API 版本管理
- 認(rèn)證授權(quán):JWT Bearer 認(rèn)證
- 數(shù)據(jù)驗(yàn)證:Model Validation
- 日志記錄:Serilog 或內(nèi)置 ILogger
- Swagger 文檔:OpenAPI 規(guī)范支持
架構(gòu)分層
API Layer (Controllers) ↓ Application Layer (Services) ↓ Domain Layer (Models, Interfaces) ↓ Infrastructure Layer (Repositories)
二、完整實(shí)現(xiàn)步驟
1. 創(chuàng)建項(xiàng)目
dotnet new webapi -n UnifiedApiDemo
2. 添加 NuGet 包
dotnet add package Microsoft.AspNetCore.Mvc.Versioning dotnet add package Swashbuckle.AspNetCore dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
三、核心代碼實(shí)現(xiàn)
1. 統(tǒng)一響應(yīng)模型
public class ApiResponse<T> { public int Code { get; set; } public string Message { get; set; } public T Data { get; set; } public DateTime Timestamp { get; } = DateTime.UtcNow; public static ApiResponse<T> Success(T data) => new() { Code = 200, Message = "Success", Data = data }; public static ApiResponse<object> Error(int code, string message) => new() { Code = code, Message = message }; }
2. 全局異常處理中間件
public class ExceptionMiddleware { private readonly RequestDelegate _next; private readonly ILogger<ExceptionMiddleware> _logger; public ExceptionMiddleware(RequestDelegate next, ILogger<ExceptionMiddleware> logger) { _next = next; _logger = logger; } public async Task InvokeAsync(HttpContext context) { try { await _next(context); } catch (Exception ex) { _logger.LogError(ex, "Global exception occurred"); await HandleExceptionAsync(context, ex); } } private static Task HandleExceptionAsync(HttpContext context, Exception exception) { context.Response.ContentType = "application/json"; context.Response.StatusCode = exception switch { ValidationException => StatusCodes.Status400BadRequest, UnauthorizedAccessException => StatusCodes.Status401Unauthorized, _ => StatusCodes.Status500InternalServerError }; return context.Response.WriteAsJsonAsync(ApiResponse<object>.Error( context.Response.StatusCode, exception.Message )); } }
3. 統(tǒng)一響應(yīng)包裝過濾器
public class ApiResponseFilter : IAsyncResultFilter { public async Task OnResultExecutionAsync( ResultExecutingContext context, ResultExecutionDelegate next) { if (context.Result is ObjectResult objResult) { var apiResponse = ApiResponse<object>.Success(objResult.Value); context.Result = new ObjectResult(apiResponse) { StatusCode = objResult.StatusCode }; } await next(); } }
4. 配置服務(wù)(Program.cs)
var builder = WebApplication.CreateBuilder(args); // 添加版本控制 builder.Services.AddApiVersioning(options => { options.DefaultApiVersion = new ApiVersion(1, 0); options.AssumeDefaultVersionWhenUnspecified = true; options.ReportApiVersions = true; }); // 配置 Swagger builder.Services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Unified API", Version = "v1" }); }); // 添加統(tǒng)一響應(yīng)過濾器 builder.Services.AddControllers(options => { options.Filters.Add<ApiResponseFilter>(); }); // 配置 JWT 認(rèn)證 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = "your_issuer", ValidateAudience = true, ValidAudience = "your_audience", ValidateLifetime = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your_secret_key")) }; }); var app = builder.Build(); // 中間件管道 app.UseSwagger(); app.UseSwaggerUI(); app.UseMiddleware<ExceptionMiddleware>(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
5. 控制器示例(帶版本控制)
[ApiController] [Route("api/v{version:apiVersion}/[controller]")] [ApiVersion("1.0")] [Authorize] public class ProductsController : ControllerBase { [HttpGet("{id}")] [ProducesResponseType(typeof(ProductDto), 200)] public IActionResult GetProduct(int id) { var product = new ProductDto { Id = id, Name = "Sample Product" }; return Ok(product); } [HttpPost] [ValidateModel] public IActionResult CreateProduct([FromBody] ProductCreateDto dto) { // 業(yè)務(wù)邏輯 return CreatedAtAction(nameof(GetProduct), new { id = 1 }, null); } }
6. 模型驗(yàn)證示例
public class ProductCreateDto { [Required] [StringLength(100)] public string Name { get; set; } [Range(0, 10000)] public decimal Price { get; set; } } public class ValidateModelAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext context) { if (!context.ModelState.IsValid) { var errors = context.ModelState .Where(e => e.Value.Errors.Count > 0) .ToDictionary( kvp => kvp.Key, kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray() ); context.Result = new BadRequestObjectResult( ApiResponse<object>.Error(400, "Validation Error", errors) ); } } }
四、運(yùn)行效果示例
成功響應(yīng)
{ "code": 200, "message": "Success", "data": { "id": 1, "name": "Sample Product" }, "timestamp": "2024-02-20T12:34:56Z" }
錯誤響應(yīng)
{ "code": 400, "message": "Validation Error", "data": { "Price": ["The field Price must be between 0 and 10000."] }, "timestamp": "2024-02-20T12:35:10Z" }
五、擴(kuò)展建議
- 性能優(yōu)化:添加響應(yīng)緩存機(jī)制
- 監(jiān)控:集成 Application Insights
- 限流:使用 AspNetCoreRateLimit
- DTO 映射:使用 AutoMapper
- 單元測試:使用 xUnit/MSTest
此方案提供了從基礎(chǔ)設(shè)施到業(yè)務(wù)邏輯的完整統(tǒng)一 API 實(shí)現(xiàn)框架,可根據(jù)具體需求進(jìn)行擴(kuò)展調(diào)整。
到此這篇關(guān)于C#中創(chuàng)建統(tǒng)一API接口的實(shí)現(xiàn)方案的文章就介紹到這了,更多相關(guān)C#創(chuàng)建統(tǒng)一API接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#利用itext實(shí)現(xiàn)PDF頁面處理與切分
這篇文章主要介紹了如何在C#中使用itext做一個pdf的頁面大小一致性處理,然后再根據(jù)數(shù)據(jù)切分出需要的pdf,感興趣的小伙伴可以了解一下2022-04-04在C#中使用二叉樹實(shí)時計(jì)算海量用戶積分排名的實(shí)現(xiàn)詳解
這篇文章主要介紹了在C#中使用二叉樹實(shí)時計(jì)算海量用戶積分排名的實(shí)現(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01.NET創(chuàng)建、刪除、復(fù)制文件夾及其子文件的實(shí)例方法
.NET創(chuàng)建、刪除、復(fù)制文件夾及其子文件的實(shí)例方法,需要的朋友可以參考一下2013-03-03