添加项目文件。

This commit is contained in:
2026-05-09 17:06:30 +08:00
parent c60f5fe117
commit 720ef957d4
378 changed files with 14843 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
using Microsoft.AspNetCore.Mvc;
namespace IM.ASPNETCore
{
public class ApiControllerBase : ControllerBase
{
}
}
+34
View File
@@ -0,0 +1,34 @@
using IM.Commons;
using IM.DomainCommons;
using Microsoft.AspNetCore.Http;
namespace IM.ASPNETCore
{
public class ExceptionMiddleware
{
private readonly RequestDelegate _next;
public ExceptionMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
try
{
await _next(context);
}
catch (DomainException ex)
{
await DomainExceptionHandlerAsync(context, ex);
}
}
public Task DomainExceptionHandlerAsync(HttpContext context, DomainException ex)
{
context.Response.ContentType = "application/json";
var result = Result<object>.Fail(ResultCode.PARAMETER_ERROR, ex.Message); // 包装成你的 Result
return context.Response.WriteAsJsonAsync(result);
}
}
}
+19
View File
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IM.Commons\IM.Commons.csproj" />
<ProjectReference Include="..\DomainCommons\IM.DomainCommons.csproj" />
</ItemGroup>
</Project>
+24
View File
@@ -0,0 +1,24 @@
using Microsoft.EntityFrameworkCore;
namespace IM.ASPNETCore
{
[AttributeUsage(AttributeTargets.Class
| AttributeTargets.Method, AllowMultiple = false, Inherited = true
)]
public class UnitOfWorkAttribute : Attribute
{
public Type[] DbContextTypes { get; private set; }
public UnitOfWorkAttribute(params Type[] dbContextTypes)
{
this.DbContextTypes = dbContextTypes;
foreach (var type in dbContextTypes)
{
if (!typeof(DbContext).IsAssignableFrom(type))
{
throw new ArgumentException($"{type} must inherit from DbContext");
}
}
}
}
}
+65
View File
@@ -0,0 +1,65 @@
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System.Reflection;
using System.Transactions;
namespace IM.ASPNETCore
{
public class UnitOfWorkFilter : IAsyncActionFilter
{
private static UnitOfWorkAttribute? GetUoWAttr(ActionDescriptor actionDesc)
{
var caDesc = actionDesc as ControllerActionDescriptor;
if (caDesc == null)
{
return null;
}
//try to get UnitOfWorkAttribute from controller,
//if there is no UnitOfWorkAttribute on controller,
//try to get UnitOfWorkAttribute from action
var uowAttr = caDesc.ControllerTypeInfo
.GetCustomAttribute<UnitOfWorkAttribute>();
if (uowAttr != null)
{
return uowAttr;
}
else
{
return caDesc.MethodInfo
.GetCustomAttribute<UnitOfWorkAttribute>();
}
}
public async Task OnActionExecutionAsync(ActionExecutingContext context,
ActionExecutionDelegate next)
{
var uowAttr = GetUoWAttr(context.ActionDescriptor);
if (uowAttr == null)
{
await next();
return;
}
using TransactionScope txScope = new(TransactionScopeAsyncFlowOption.Enabled);
List<DbContext> dbCtxs = new List<DbContext>();
foreach (var dbCtxType in uowAttr.DbContextTypes)
{
//用HttpContext的RequestServices
//确保获取的是和请求相关的Scope实例
var sp = context.HttpContext.RequestServices;
DbContext dbCtx = (DbContext)sp.GetRequiredService(dbCtxType);
dbCtxs.Add(dbCtx);
}
var result = await next();
if (result.Exception == null)
{
foreach (var dbCtx in dbCtxs)
{
await dbCtx.SaveChangesAsync();
}
txScope.Complete();
}
}
}
}
+27
View File
@@ -0,0 +1,27 @@
using IM.Commons;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace IM.ASPNETCore
{
public class ValidatorFilter : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
}
public void OnActionExecuting(ActionExecutingContext context)
{
if (context.ModelState.IsValid) return;
var errors = context.ModelState.Where(x => x.Value.Errors.Count() > 0).ToList();
var errMsg = errors.FirstOrDefault().Value?.Errors.First().ErrorMessage
?? ResultCode.PARAMETER_ERROR.GetDescription();
var result = Result<object>.Fail(ResultCode.PARAMETER_ERROR, errMsg);
context.Result = new OkObjectResult(result);
}
}
}