在本文中,我們將介紹如何使用 .NET Core 中的中間件來自定義規範響應,以便在 API 調用時返回統一的格式和錯誤信息。中間件是一種可以在請求和響應管道中執行邏輯的軟體組件,它可以對請求或響應進行修改、攔截或處理。我們將使用一個簡單的示例來演示如何創建和使用自定義規範響應的中間件。 首先,我們 ...
在本文中,我們將介紹如何使用 .NET Core 中的中間件來自定義規範響應,以便在 API 調用時返回統一的格式和錯誤信息。中間件是一種可以在請求和響應管道中執行邏輯的軟體組件,它可以對請求或響應進行修改、攔截或處理。我們將使用一個簡單的示例來演示如何創建和使用自定義規範響應的中間件。
首先,我們需要創建一個類來表示規範響應的格式,這個類可以包含以下屬性:
Code
:響應的狀態碼,例如 200 表示成功,400 表示客戶端錯誤,500 表示伺服器錯誤等。Message
:響應的消息,例如 "OK" 表示成功,"Bad Request" 表示客戶端錯誤,"Internal Server Error" 表示伺服器錯誤等。Data
:響應的數據,可以是任意類型的對象,例如用戶信息、產品列表、訂單詳情等。
這個類的代碼如下:
public class ApiResponse
{
public bool Success { get; set; }
public string Message { get; set; }
public object Data { get; set; }
public ApiResponse(bool success, string message, object data)
{
Success = success;
Message = message;
Data = data;
}
public ApiResponse(bool success, string message)
: this(success, message, null)
{
}
public ApiResponse(bool success)
: this(success, null, null)
{
}
}
中間件
接下來,我們需要創建一個中間件類來實現自定義規範響應的邏輯,這個類需要有以下特點:
- 接收一個
RequestDelegate
類型的參數,表示下一個中間件或終端處理程式。 - 實現一個
InvokeAsync
方法,接收一個HttpContext
類型的參數,表示當前請求的上下文。 - 在
InvokeAsync
方法中,使用await next(context)
來調用下一個中間件或終端處理程式,並獲取其返回的響應。 - 在
InvokeAsync
方法中,根據響應的狀態碼和內容來構造一個ApiResponse
對象,並將其序列化為 JSON 格式。 - 在
InvokeAsync
方法中,修改響應的內容類型為application/json
,並將 JSON 格式的ApiResponse
寫入到響應體中。 GetStatusCodeMessage()
根據響應狀態給出信息GetResponseData()
獲取其返回的響應
CustomResponseMiddleware
public class CustomResponseMiddleware
{
private readonly RequestDelegate _next;
public CustomResponseMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
var originalBodyStream = context.Response.Body;
using (var responseBody = new MemoryStream())
{
context.Response.Body = responseBody;
await _next(context);
if (context.Response.StatusCode >= 400 && context.Response.StatusCode <= 599)
{
context.Response.ContentType = "application/json";
var response = new ApiResponse
{
Success = false,
Message = GetStatusCodeMessage(context.Response.StatusCode),
Data = await GetResponseData(context.Response)
};
var jsonResponse = JsonConvert.SerializeObject(response);
await context.Response.WriteAsync(jsonResponse, Encoding.UTF8);
}
else
{
context.Response.ContentType = "application/json";
var response = new ApiResponse
{
Success = true,
Message = GetStatusCodeMessage(context.Response.StatusCode),
Data = await GetResponseData(context.Response)
};
var jsonResponse = JsonConvert.SerializeObject(response);
await context.Response.WriteAsync(jsonResponse, Encoding.UTF8);
}
await responseBody.CopyToAsync(originalBodyStream);
}
}
}
GetStatusCodeMessage()
private static string GetStatusCodeMessage(int statusCode)
{
switch (statusCode)
{
case 200:
return "OK";
case 201:
return "Created";
case 204:
return "No Content";
case 400:
return "Bad Request";
case 401:
return "Unauthorized";
case 403:
return "Forbidden";
case 404:
return "Not Found";
case 500:
return "Internal Server Error";
default:
return "Unknown Status Code";
}
}
GetResponseData()
private async Task<object> GetResponseData(HttpResponse response)
{
var body = await new StreamReader(response.Body).ReadToEndAsync();
response.Body.Seek(0, SeekOrigin.Begin);
try
{
return JsonConvert.DeserializeObject(body);
}
catch (JsonReaderException)
{
return new { Message = body };
}
}
在上面的示例中,我們創建了一個名為 CustomResponseMiddleware 的中間件。該中間件攔截每個響應,並根據需要修改響應格式。具體來說,如果響應的狀態碼為 4xx 或5xx,則中間件將返回一個包含錯誤消息和數據的 ApiResponse 對象;否則,中間件將返回一個包含成功消息和數據的 ApiResponse 對象。
常用類
定義常用的類可以幫助我們標準化 ASP.NET Core 應用程式中的響應格式,提高代碼重用性,並使前端更加輕鬆地處理所有響應。
除了 ApiResponse 類之外,還可以定義其他常用類,如 ApiError 類、ApiResponse
下麵是 ApiError 類的示例代碼:
public class ApiError
{
public int StatusCode { get; set; }
public string Message { get; set; }
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
}
ApiError
類包含兩個屬性:StatusCode
和 Message
。StatusCode
屬性指示錯誤的狀態碼,Message 屬性包含有關錯誤的消息。
使用 ApiError 類可以幫助我們標準化應用程式中的錯誤響應格式。例如,在某些情況下,我們可能需要返回一個包含單個錯誤消息的響應,而在其他情況下,我們可能需要返回一個包含多個錯誤消息的響應。通過使用 ApiError 類,我們可以在應用程式中統一處理這些情況,並返回一個標準的錯誤響應格式。
結論
通過使用 ASP.NET Core 中間件和常用類,我們可以自定義 ASP.NET Core 應用程式中的響應格式,並標準化應用程式中的響應格式。這可以提高代碼重用性,並使前端更加輕鬆地處理所有響應。在開發 ASP.NET Core 應用程式時,我們應該始終考慮使用中間件和常用類來提高代碼的可讀性、可維護性和可重用性。