网站建设公司网站源码,网站备案是域名备案还是主机备案,石家庄定制网站建设公司,各大网站官网的导航栏怎么做.NET 7 中的 HttpResult 接口Intro在前面的文章中#xff0c;我们提到了 .NET 7 引入了 Endpoint Filter 来支持 Endpoint 的过滤器#xff0c;有了这个接口就想着把之前的统一 API response 的 filter 改造一下支持 endpoint filter#xff0c;然而这个一直等到了 .NET 7 P….NET 7 中的 HttpResult 接口Intro在前面的文章中我们提到了 .NET 7 引入了 Endpoint Filter 来支持 Endpoint 的过滤器有了这个接口就想着把之前的统一 API response 的 filter 改造一下支持 endpoint filter然而这个一直等到了 .NET 7 Preview 7 才得以实现在 .NET 7 Preview 7 中引入了一些接口使得我们可以匹配 HttpResult 的类型HttpResult Interface.NET 6 开始引入了 Minimal API, 但是要匹配一系列 IResult 相关的 response 比如 Results.Ok, Results.NotFound 会比较困难在 .NET 7 有了一些改进在 .NET 7 Preview 3 中出于方便单元测试的考虑开放了一些 HttpResult 的类型比如OkObjectHttpResult/NotFoundHttpResult 等但是始终没有一个类似于 MVC 里的 ObjectResult 一样的类型使得我们如果想要匹配 response 的类型就会很麻烦终于在 .NET 7 Preview 7引入了一系列的接口我们可以通过这些接口进行模式匹配来获取这些 HttpResult 中的 Value/StatusCode 等等新增加的接口如下Microsoft.AspNetCore.Http.IContentTypeHttpResult
Microsoft.AspNetCore.Http.IFileHttpResult
Microsoft.AspNetCore.Http.INestedHttpResult
Microsoft.AspNetCore.Http.IStatusCodeHttpResult
Microsoft.AspNetCore.Http.IValueHttpResult
Microsoft.AspNetCore.Http.IValueHttpResultTValue可以参考 PRhttps://github.com/dotnet/aspnetcore/pull/42385/files如果我们想要匹配 response 的返回值就可以使用 IValueHttpResult 来匹配比如if (result is IValueHttpResult valueHttpResult)return valueHttpResult.Value;也可以使用 IStatusCodeHttpResult 来匹配 response statusif (result is IStatusCodeHttpResult statusCodeResult)return statusCodeResult.StatusCode;ApiResultFilter实现了一个简单的统一 response 的 ApiResultFilter 在原来的基础上增加了 EndpointFilter 的支持实现如下[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple false, Inherited true)]
public sealed class ApiResultFilter : Attribute, IResultFilter, IExceptionFilter
#if NET7_0_OR_GREATER, IEndpointFilter
#endif{public void OnResultExecuting(ResultExecutingContext context){if (context.Result is ObjectResult { Value: not Result } objectResult){var result new Resultobject(){Data objectResult.Value,Status HttpStatusCode2ResultStatus(objectResult.StatusCode)};objectResult.Value result;}}public void OnResultExecuted(ResultExecutedContext context){}public void OnException(ExceptionContext context){var result Result.Fail(context.Exception.ToString(), ResultStatus.ProcessFail);context.Result new ObjectResult(result) { StatusCode 500 };}
#if NET7_0_OR_GREATERpublic async ValueTaskobject InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next){try{var result await next(context);if (result is Result or ObjectResult { Value: Result } or IValueHttpResult { Value: Result }){return result;}if (result is ObjectResult { Value: not Result } objectResult){return new Resultobject(){Data objectResult.Value, Status HttpStatusCode2ResultStatus(objectResult.StatusCode)};}if (result is IValueHttpResult { Value: not Result } valueHttpResult){var status result is IStatusCodeHttpResult statusCodeHttpResult? HttpStatusCode2ResultStatus(statusCodeHttpResult.StatusCode): HttpStatusCode2ResultStatus(200);return new Resultobject() { Data valueHttpResult.Value, Status status };}return new Resultobject(){Data result, Status HttpStatusCode2ResultStatus(context.HttpContext.Response.StatusCode)};}catch (Exception ex){return Result.Fail(ex.ToString(), ResultStatus.ProcessFail);}}
#endifprivate static ResultStatus HttpStatusCode2ResultStatus(int? statusCode){statusCode ?? 200;var status ResultStatus.Success;if (Enum.IsDefined(typeof(ResultStatus), statusCode.Value)){status (ResultStatus)statusCode.Value;}if (status ResultStatus.None){status ResultStatus.Success;}return status;}
}下面看一个使用的示例var app WebApplication.Create(args);
app.Map(/Hello, () Hello Minimal API!).AddEndpointFilterApiResultFilter();
app.Map(/HelloV3, () Results.Ok(new { Name test })).AddEndpointFilterApiResultFilter();
app.Map(/HelloV4, () Results.Ok(Result.Success(new { Name test }))).AddEndpointFilterApiResultFilter();
await app.RunAsync();访问一个直接返回一个字符串的接口访问返回一个 IResult 的接口访问返回一个 ResultModel 的 API使用控制器 API 示例[Route(api/[controller])]
public class ValuesController: ControllerBase
{[HttpGet([action])]public IActionResult Test(){return Ok(new { Name Amazing .NET });}
}API response 示例Referenceshttps://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-7-preview-7/#new-httpresults-interfaceshttps://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-7-preview-3/#improved-unit-testability-for-minimal-route-handlershttps://github.com/dotnet/aspnetcore/issues/41470https://github.com/dotnet/aspnetcore/issues/42187https://github.com/dotnet/aspnetcore/pull/42385/fileshttps://github.com/WeihanLi/WeihanLi.Web.Extensions/tree/dev/samples/WeihanLi.Web.Extensions.Samples