diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..4abb871 --- /dev/null +++ b/404.html @@ -0,0 +1,1221 @@ + + + +
+ + + + + + + + + + + + + + + + + + +基于本项目采用的代码组织方式,每个类型例如领域模型
、命令处理器
、事件处理器
等等都有明确的职责和能力,这对AI工具的辅助使用非常友好,AI工具可以根据你编写代码的文件模型和上下文准确推断出意图并给予代码补全提示,并且随着你的项目代码的增多,AI工具的智能程度会越来越高。
因此,非常推荐使用AI工具来辅助编写代码,这样可以大大提高编码效率。
+下面一些技巧可以帮助AI工具更好地辅助你编写代码:
+推荐使用 GitHub Copilot 来作为代码辅助工具,它支持多种编辑器,例如Visual Studio Code
、Visual Studio
、JetBrains Rider
等等。
我们在包NetCorePal.Extensions.Primitives
中定义了一个异常类KnownException
,用于表示已知异常,使得系统可以更友好的方式响应异常。
KnownException
实现了接口 IKnownException
,可以携带Message
、ErrorCode
、ErrorData
等更多的信息,接口定义如下:
public interface IKnownException
+{
+ string Message { get; }
+
+ int ErrorCode { get; }
+
+ IEnumerable<object> ErrorData { get; }
+}
+
我们在包NetCorePal.Extensions.AspNetCore
中定义了一个异常处理中间件KnownExceptionHandleMiddleware
,用于处理异常。
KnownExceptionHandleMiddleware
会捕获已知异常,并将异常信息转换为ResponseData
对象,然后返回给客户端,从而保持正常响应与异常响应具有相同的数据结构,方便前端处理。
如果异常不是已知异常,则会返回一个默认的错误信息,以屏蔽敏感信息,避免暴露系统内部异常。
+使用方法如下,在Program.cs
文件中:
var builder = WebApplication.CreateBuilder(args);
+
+//Add Other Services
+
+var app = builder.Build();
+app.UseKnownExceptionHandler();
+
KnownExceptionHandleMiddleware
的配置选项如下:
KnownExceptionStatusCode
: 已知异常响应状态码,默认为HttpStatusCode.OK
,即200
;UnknownExceptionStatusCode
: 非已知异常响应状态码,默认为HttpStatusCode.InternalServerError
,即500
;UnknownExceptionMessage
: 非已知异常响应消息,默认为"未知错误"
;UnknownExceptionCode
: 非已知异常响应错误码,默认为99999
;具体代码定义如下:
+public class KnownExceptionHandleMiddlewareOptions
+{
+ public HttpStatusCode KnownExceptionStatusCode { get; set; } = HttpStatusCode.OK;
+ public HttpStatusCode UnknownExceptionStatusCode { get; set; } = HttpStatusCode.InternalServerError;
+ public string UnknownExceptionMessage { get; set; } = "未知错误";
+ public int UnknownExceptionCode { get; set; } = 99999;
+}
+
KnownExceptionHandleMiddleware
支持动态配置,通过注册一个工厂方法来实现:
Func<HttpContext, KnownExceptionHandleMiddlewareOptions>
+
下面是一个示例,当请求路径以/api/internal
开头时,使用option1
,否则使用option2
:
var app = builder.Build();
+
+var option1 = new KnownExceptionHandleMiddlewareOptions {
+ KnownExceptionStatusCode = HttpStatusCode.InternalServerError,
+ UnknownExceptionStatusCode = HttpStatusCode.InternalServerError,
+ UnknownExceptionMessage = "未知错误",
+ UnknownExceptionCode = 99999
+};
+var option2 = new KnownExceptionHandleMiddlewareOptions {
+ KnownExceptionStatusCode = HttpStatusCode.OK,
+ UnknownExceptionStatusCode = HttpStatusCode.BadRequest,
+ UnknownExceptionMessage = "未知错误",
+ UnknownExceptionCode = 10000
+};
+
+app.UseKnownExceptionHandler(httpContext => {
+ if(httpContext.Request.Path.StartsWithSegments("/api/internal")) {
+ return option1;
+ }
+ else {
+ return option2;
+ }
+});
+
为了让客户端能够更好地处理响应数据,我们需要对数据进行封装,使用一致的数据格式,这样客户端就可以根据数据格式进行统一的处理。
+我们在包NetCorePal.Extensions.AspNetCore
中定义了两个类来封装响应数据,分别是 ResponseData
和 ResponseData<T>
。
ResponseData
类用于封装不带数据的响应,ResponseData<T>
类用于封装带数据的响应。
类型定义如下:
+public class ResponseData
+{
+ public ResponseData(bool success = true, string message = "", int code = 0, IEnumerable<object>? errorData = null)
+ {
+ Success = success;
+ Message = message;
+ Code = code;
+ ErrorData = errorData ?? KnownException.EmptyErrorData;
+ }
+
+ public bool Success { get; protected set; }
+ public string Message { get; protected set; }
+ public int Code { get; protected set; }
+
+ public IEnumerable<object> ErrorData { get; protected set; }
+}
+
+
+public class ResponseData<T> : ResponseData
+{
+ public ResponseData(T data, bool success = true, string message = "", int code = 0, IEnumerable<object>? errorData = null) : base(success: success, message: message, code: code, errorData: errorData)
+ {
+ this.Data = data;
+ }
+ public T Data { get; protected set; }
+}
+
我们还定义了一个扩展方法 AsResponseData
,用于将数据转换为 ResponseData
或 ResponseData<T>
对象。
using NetCorePal.Extensions.AspNetCore;
+
+var data = new MyData();
+var responseData = data.AsResponseData();
+
在控制器中,我们可以使用 ResponseData
和 ResponseData<T>
来封装响应数据。
[HttpGet]
+public async Task<ResponseData<IEnumerable<WeatherForecast>>> Get()
+{
+ var rng = new Random();
+ var result = await Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
+ {
+ Date = DateTime.Now.AddDays(index),
+ TemperatureC = rng.Next(-20, 55),
+ Summary = Summaries[rng.Next(Summaries.Length)]
+ }));
+
+ return result.AsResponseData();
+}
+