网上找到的资料基本上都是用在中间件里面的代码,但是我在项目里面有一些是静态的方法,有的是在过滤器(权限拦截)里面使用。
中间件里的办法就不适用了。
比如下面这个方法(从Asp.net 当中移植过来的):
也试过一些诸如 HttpContext.Abort();
content.Response.StatusCode = StatusCodes.Status200OK;
结果都不行。
需要说明的是,Response.End 能够实现很多功能,没找到替代的:
中止当前流输出
阻断其它中间件的后续处理。
可能有一个勉强替代的办法,那就是抛出异常,然后让外部的异常拦截器做处理。
但是我这种程序员觉得异常是不好的东西,要尽量勉强产生异常、抛出异常。
Filter 里可以直接设置 context.Result
https://github.com/huiyuanai709/AspNetCore.ResponseWrapper/blob/main/src/AspNetCore.ResponseWrapper/Mvc/Filters/ModelInvalidWrapperFilter.cs
不想抛异常,你可以直接用 go 类似得语法,Tuple 很早就支持了吧,Controller 直接返回 IActionResult,结合ProducesResponseTypeAttribute 可以在api 文档上看到真实得响应结构
试下关闭响应,新版本可能必须要求用FlushAsync()
HttpResponse.Body.Flush();
HttpResponse.Body.Close();
你可以Nuget搜并引入CYQ.Data,然后在Starups或Program项目中添加:
using Microsoft.AspNetCore.Http;
服务:
services.AddHttpContext();
配置:
app.UseHttpContext();
立即就可以兼容.net framework系列了。
这个我有经验,网站找的解决方案看运气,运气好他们的方法就是管用的,更多的情况是没用。
因为,这一切的源头和版本有关,和请示处理执行顺序有关,asp.net 到 asp.net core 更新换代中产生了很多不同的版本,这些版本大体上是兼容的,还涉及到这些实现细节还是有一些区别。
要解决你的问题,首先搞清楚你现在用的 asp.net core 版本是多少,控制器用的什么(是ASP.NET Core MVC视图还是ASP.NET Core WebApi )。
然后去官网看相应版本的文档,看高级里的过滤器章节,搞清楚框架处理流程,找一个合适的节点处理即可。
https://docs.microsoft.com/zh-cn/aspnet/core/mvc/controllers/filters?view=aspnetcore-6.0 (asp.net core6.0版本文档)
说了这么多,还是不能解决你眼下的问题。但我上面说的那些不是废话,建议你多看看,看懂了自然就有解决方法。
你要的实操代码:
public class HttpResponseMessageOutputFormatter : IOutputFormatter
{
public bool CanWriteResult(OutputFormatterCanWriteContext context)
{
return context.Object is HttpResponseMessage;
}
public async Task WriteAsync(OutputFormatterWriteContext context)
{
var response = context.HttpContext.Response;
var responseMessage = context.Object as HttpResponseMessage;
if (responseMessage == null)
{
throw new InvalidOperationException("");
}
using (responseMessage)
{
response.StatusCode = (int)responseMessage.StatusCode;
var responseFeature = context.HttpContext.Features.Get<IHttpResponseFeature>();
if (responseFeature != null)
{
responseFeature.ReasonPhrase = responseMessage.ReasonPhrase;
}
var responseHeaders = responseMessage.Headers;
// Ignore the Transfer-Encoding header if it is just "chunked".
// We let the host decide about whether the response should be chunked or not.
if (responseHeaders.TransferEncodingChunked == true &&
responseHeaders.TransferEncoding.Count == 1)
{
responseHeaders.TransferEncoding.Clear();
}
foreach (var header in responseHeaders)
{
response.Headers.Append(header.Key, header.Value.ToArray());
}
if (responseMessage.Content != null)
{
var contentHeaders = responseMessage.Content.Headers;
// Copy the response content headers only after ensuring they are complete.
// We ask for Content-Length first because HttpContent lazily computes this
// and only afterwards writes the value into the content headers.
var unused = contentHeaders.ContentLength;
foreach (var header in contentHeaders)
{
response.Headers.Append(header.Key, header.Value.ToArray());
}
await responseMessage.Content.CopyToAsync(response.Body);
}
}
}
}