簡介
ControllerBase 是 ASP.NET Core 中構建 Web API 控制器的基類,位於 Microsoft.AspNetCore.Mvc 命名空間。它提供了豐富的功能來處理 HTTP 請求,但不包含視圖支持。
核心功能:
HTTP響應:提供方法(如Ok、NotFound)生成標準HTTP響應。- 模型綁定:自動將請求數據綁定到參數(如查詢字符串、請求體)。
- 驗證支持:結合
[ApiController]實現自動模型驗證。 - 異步友好:支持
async/await處理高併發請求。 - 輕量設計:不包含
MVC視圖相關的功能,適合API場景。
ControllerBase 的定位
- 位於命名空間
Microsoft.AspNetCore.Mvc,是所有Web API控制器的基類。 - 與 MVC 的
Controller相比,ControllerBase不包含視圖(Razor)相關功能,僅提供 內容結果、狀態碼、路由綁定、模型驗證 等Web API核心支持。 - 通常搭配
[ApiController]特性使用,開啓自動模型驗證、參數綁定規則和返回行為。
繼承體系
object
└─ ControllerBase
├─ Controller // 包含 View()、PartialView() 等 MVC 視圖方法
└─ 用户自定義 Controllers…
-
ControllerBase- 提供結果工廠方法(
Ok(), CreatedAtAction()等) - 包含屬性如
Request、Response、ModelState、User - 實現接口
IActionFilterMetadata、IActionResult等元數據標記
- 提供結果工廠方法(
-
Controller(典型用於MVC)- 繼承自
ControllerBase並額外添加視圖渲染方法
- 繼承自
構造注入與內置屬性
在自定義 API 控制器中,通常這樣聲明:
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private readonly IProductService _svc;
public ProductsController(IProductService svc)
{
_svc = svc;
}
// Action 方法…
}
-
[ApiController]- 自動執行模型驗證,錯誤時直接返回 400
- 簡化參數綁定(如
[FromBody]、[FromQuery]默認行為)
-
Route、HttpXXX特性- 定義路由模板與
HTTP動作要匹配的請求
- 定義路由模板與
常用內置屬性
| 屬性 | 説明 |
|---|---|
HttpContext |
當前請求上下文 |
Request |
快速訪問 HttpContext.Request |
Response |
快速訪問 HttpContext.Response |
User |
當前認證用户的 ClaimsPrincipal |
RouteData |
路由參數及其綁定值 |
ModelState |
模型驗證狀態與錯誤詳情 |
結果工廠方法
ControllerBase 提供一系列返回 ActionResult 的方法,用於快速構造 HTTP 響應:
成功響應
| 方法 | HTTP 狀態碼 | 説明 |
|---|---|---|
Ok() / Ok(object value) |
200 | 返回 200,帶或不帶響應體 |
Created(string uri, object value) |
201 | 資源已創建,Location 頭部指定新資源 URI |
CreatedAtAction(...) / CreatedAtRoute(...) |
201 | 指定路由或動作生成 Location |
NoContent() |
204 | 成功但無響應體 |
客户端錯誤
| 方法 | HTTP 狀態碼 | 説明 |
|---|---|---|
BadRequest() / BadRequest(object error) |
400 | 返回模型驗證錯誤或自定義錯誤消息 |
Unauthorized() |
401 | 未認證 |
Forbid() |
403 | 無訪問權限 |
NotFound() / NotFound(object value) |
404 | 資源未找到 |
Conflict() |
409 | 衝突,如重複資源 |
UnsupportedMediaType() |
415 | 不支持的媒體類型 |
服務端錯誤
| 方法 | HTTP 狀態碼 | 説明 |
|---|---|---|
StatusCode(int statusCode) |
自定義 | 返回任意狀態碼 |
Problem() |
500+ | 按 RFC 7807 生成標準化錯誤響應體 |
Tip: 這些工廠方法本質上返回了實現 IActionResult 的對象,框架在管道末端執行並寫入 HTTP。
核心功能詳解
HTTP 響應方法
狀態碼響應
[HttpGet("{id}")]
public IActionResult GetProduct(int id)
{
var product = _repository.Get(id);
if (product == null)
return NotFound(); // 404
return Ok(product); // 200 + 數據
}
文件響應
[HttpGet("download/{fileName}")]
public IActionResult DownloadFile(string fileName)
{
var filePath = Path.Combine(_env.ContentRootPath, "Files", fileName);
if (!System.IO.File.Exists(filePath))
return NotFound();
var fileBytes = System.IO.File.ReadAllBytes(filePath);
return File(fileBytes, "application/octet-stream", fileName);
}
請求上下文訪問
常用屬性
public class ProductsController : ControllerBase
{
[HttpGet("info")]
public IActionResult GetInfo()
{
// 獲取請求信息
var method = Request.Method;
var contentType = Request.ContentType;
// 獲取用户信息
var userName = User.Identity?.Name;
var isAdmin = User.IsInRole("Admin");
// 獲取路由數據
var routeId = RouteData.Values["id"];
return Ok(new { method, userName });
}
}
模型綁定與驗證
-
自動驗證(啓用
[ApiController]時)- 在
Action執行前對標註了驗證特性的模型進行驗證 ModelState.IsValid == false則自動返回 400Bad Request,響應體包含錯誤詳情
- 在
[HttpPost]
public IActionResult CreateProduct(
[FromBody] Product product, // 從JSON綁定
[FromQuery] string category, // 從查詢字符串綁定
[FromHeader] string apiKey) // 從請求頭綁定
{
// 自動模型驗證
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// 業務邏輯處理
var createdProduct = _service.Create(product, category);
return CreatedAtAction(nameof(GetProduct),
new { id = createdProduct.Id }, createdProduct);
}
高級功能與最佳實踐
操作結果包裝
自定義統一響應格式
public class ApiResult<T> : IActionResult
{
public T Data { get; }
public int StatusCode { get; }
public string? Message { get; }
public ApiResult(T data, int statusCode = 200, string? message = null)
{
Data = data;
StatusCode = statusCode;
Message = message;
}
public async Task ExecuteResultAsync(ActionContext context)
{
var result = new ObjectResult(new
{
Success = StatusCode >= 200 && StatusCode < 300,
Data,
Message,
Timestamp = DateTime.UtcNow
})
{
StatusCode = StatusCode
};
await result.ExecuteResultAsync(context);
}
}
// 在控制器中使用
[HttpGet("{id}")]
public ApiResult<Product> GetProduct(int id)
{
var product = _repository.Get(id);
return product == null
? new ApiResult<Product>(null, 404, "Product not found")
: new ApiResult<Product>(product);
}
內容協商
支持多種響應格式
[ApiController]
[Route("api/[controller]")]
[Produces("application/json", "application/xml")] // 支持的響應類型
public class ProductsController : ControllerBase
{
[HttpGet]
public ActionResult<IEnumerable<Product>> GetAll()
{
return _repository.GetAll();
}
}
API 版本控制
實現 API 版本管理
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
public class ProductsController : ControllerBase
{
[HttpGet]
[MapToApiVersion("1.0")]
public IEnumerable<Product> GetV1()
{
// 版本1.0的實現
}
[HttpGet]
[MapToApiVersion("2.0")]
public ActionResult<IEnumerable<ProductDto>> GetV2()
{
// 版本2.0的實現
}
}
異步支持
ControllerBase建議寫 異步Action,返回Task<IActionResult>或直接Task<T>(結合泛型ActionResult<T>):
[HttpGet("{id}")]
public async Task<ActionResult<Product>> Get(int id)
{
var p = await _svc.FindAsync(id);
return p is null ? NotFound() : Ok(p);
}
-
ActionResult<T>(.NET Core 2.1+)- 允許方法既返回
T(自動包裝為 200)也返回ActionResult(可自定義狀態碼)。
- 允許方法既返回
過濾器與管道
-
ControllerBase支持註冊和應用各種 過濾器:- 授權過濾器(
[Authorize]) - 資源過濾器(
IResourceFilter) - 動作過濾器(
IActionFilter) - 異常過濾器(
IExceptionFilter) - 結果過濾器(
IResultFilter)
- 授權過濾器(
- 示例:全局註冊
services.AddControllers(options =>
{
options.Filters.Add<GlobalExceptionFilter>();
});
- 示例:單控制器/Action 應用
[TypeFilter(typeof(LogActionFilter))]
public class MyController : ControllerBase { … }
安全最佳實踐
身份驗證與授權
[ApiController]
[Authorize] // 控制器級別要求認證
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
[HttpGet]
[Authorize(Roles = "Admin")] // 要求管理員角色
public IActionResult GetAllOrders() { /* ... */ }
[HttpGet("my")]
public IActionResult GetMyOrders()
{
// 獲取當前用户ID
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
return Ok(_repository.GetOrdersByUser(userId));
}
[HttpPost]
[Authorize(Policy = "RequireVerifiedEmail")] // 使用自定義策略
public IActionResult CreateOrder([FromBody] Order order) { /* ... */ }
}
跨域資源共享 (CORS)
[ApiController]
[Route("api/[controller]")]
[EnableCors("AllowSpecificOrigin")] // 啓用CORS策略
public class PublicDataController : ControllerBase
{
[HttpGet]
public IActionResult GetPublicData() { /* ... */ }
}
// 在Startup中配置CORS策略
services.AddCors(options =>
{
options.AddPolicy("AllowSpecificOrigin",
builder => builder.WithOrigins("https://example.com")
.AllowAnyMethod()
.AllowAnyHeader());
});
常見問題解決方案
模型驗證統一處理
// 創建統一驗證過濾器
public class ValidateModelAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (!context.ModelState.IsValid)
{
context.Result = new BadRequestObjectResult(new
{
Code = 400,
Message = "參數驗證失敗",
Errors = context.ModelState
.SelectMany(m => m.Value.Errors)
.Select(e => e.ErrorMessage)
});
}
}
}
// 全局註冊
services.AddControllers(options =>
{
options.Filters.Add<ValidateModelAttribute>();
});
全局異常處理
public class ApiExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
var exception = context.Exception;
var statusCode = exception switch
{
NotFoundException => 404,
ValidationException => 400,
UnauthorizedAccessException => 401,
_ => 500
};
context.Result = new ObjectResult(new
{
Code = statusCode,
Message = exception.Message
})
{
StatusCode = statusCode
};
context.ExceptionHandled = true;
}
}
ControllerBase 最佳實踐總結
API 設計規範
// 使用HTTP動詞特性
[HttpGet("{id}")]
[HttpPost]
[HttpPut("{id}")]
[HttpDelete("{id}")]
響應類型聲
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(Product))]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IActionResult GetProduct(int id) { /* ... */ }
異步優先
public async Task<IActionResult> Get() { /* ... */ }
依賴注入
public MyController(IMyService service) { /* ... */ }
安全加固
[Authorize]
[ValidateAntiForgeryToken]
[EnableCors("SafePolicy")]
版本管理
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
統一響應格式
return Ok(new { Data = result, Message = "Success" });
資源和文檔
-
官方文檔:
Microsoft Learn:https://learn.microsoft.com/en-us/aspnet/core/mvc/controllersControllerBase:https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnet...
NuGet包:https://www.nuget.org/packages/Microsoft.AspNetCore.Mvc.CoreGitHub:https://github.com/dotnet/aspnetcore