Asp.Net Core 2 中是不是有等效于“HttpContext.Response.Write”的内容?
Posted
技术标签:
【中文标题】Asp.Net Core 2 中是不是有等效于“HttpContext.Response.Write”的内容?【英文标题】:Is there an equivalent to "HttpContext.Response.Write" in Asp.Net Core 2?Asp.Net Core 2 中是否有等效于“HttpContext.Response.Write”的内容? 【发布时间】:2018-05-01 05:08:05 【问题描述】:我正在尝试使用 Asp.Net Core 2 中的 ActionFilter 在页面上附加一些 html 和 javascript 内容。
在 MVC 中,它正在使用
filterContext.HttpContext.Response.Write(stringBuilder.ToString());
但在 Core 中它不起作用。
我试图用这个来实现:
filterContext.HttpContext.Response.WriteAsync(stringBuilder.ToString());
但它会使整个页面变为空白。
我正在寻找构建于 Asp.Core 2.0 中的 nopCommerce 4.0 解决方案
【问题讨论】:
【参考方案1】:静态和异步方法HttpResponseWritingExtensions.WriteAsync
是目前实现这一目标的首选方式。
目前,您可以在程序集Assembly Microsoft.AspNetCore.Http.Abstractions
中找到它。
using Microsoft.AspNetCore.Http;
[HttpGet("test")]
public async Task GetTest()
=> await HttpResponseWritingExtensions.WriteAsync(this.Response, "Hello World");
2022 年 2 月 23 日更新
与主题有点相关。使用 ASP.NET Core 6.0,您可以使用 Minimal API 编写一个简单的响应,如下所示:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World");
app.Run();
Source: MSDN
【讨论】:
【参考方案2】:Response.Body.Write 将字节数组作为参数。
public void OnGet()
var text = "<h1>Hello, Response!</h1>";
byte[] data = System.Text.Encoding.UTF8.GetBytes(text);
Response.Body.Write(data, 0, data.Length);
或异步版本:
public async Task OnGetAsync()
var text = "<h1>Hello, Async Response!</h1>";
byte[] data = System.Text.Encoding.UTF8.GetBytes(text);
await Response.Body.WriteAsync(data, 0, data.Length);
【讨论】:
确保从 razor 页面中删除或评论我们的默认内容,因为 Response.Body.Write 接管页面响应 ` @* @section Scripts @await Html.RenderPartialAsync("_ValidationScriptsPartial"); *@`【参考方案3】:你可以试试这样的
在INopStartup.Configure(IApplicationBuilder 应用程序)的自定义实现中
application.Use(async (context, next) =>
using (var customStream = new MemoryStream())
// Create a backup of the original response stream
var backup = context.Response.Body;
// Assign readable/writeable stream
context.Response.Body = customStream;
await next();
// Restore the response stream
context.Response.Body = backup;
// Move to start and read response content
customStream.Seek(0, SeekOrigin.Begin);
var content = new StreamReader(customStream).ReadToEnd();
// Write custom content to response
await context.Response.WriteAsync(content);
);
比在你的自定义 ResultFilterAttribute
public class MyAttribute : ResultFilterAttribute
public override void OnResultExecuted(ResultExecutedContext context)
try
var bytes = Encoding.UTF8.GetBytes("Foo Bar");
// Seek to end
context.HttpContext.Response.Body.Seek(context.HttpContext.Response.Body.Length, SeekOrigin.Begin);
context.HttpContext.Response.Body.Write(bytes, 0, bytes.Length);
catch
// ignored
base.OnResultExecuted(context);
结果
希望这有助于进入正确的道路。
【讨论】:
如果我们在 nopCommerce 中使用这个解决方案,我们就会遇到问题。在INopStartup.Configure方法中,如果我们先调用await next()然后恢复响应流,它不会加载图片和脚本用户端报错 Response Content-Length mismatch:too many byteswritten. 如果我们先恢复响应流然后调用 await next() 那么它会在 filterContext.HttpContext 报错.Response.Body.Seek() 方法未找到.【参考方案4】:我的代码没有为异步执行做好准备,所以我使用了:
Response.WriteAsync("text").Wait();
.Wait() 使执行等待异步方法完成执行以继续。
不知道性能是不是最好,但已经比.Net Framework方案好
.Wait(): https://docs.microsoft.com/pt-br/dotnet/api/system.io.stream.writeasync?view=net-6.0
.WriteAsync():https://docs.microsoft.com/pt-br/dotnet/api/system.threading.tasks.task.wait?view=net-6.0
【讨论】:
以上是关于Asp.Net Core 2 中是不是有等效于“HttpContext.Response.Write”的内容?的主要内容,如果未能解决你的问题,请参考以下文章
与 Request.RequestURI 等效的 ASP.NET Core MVC 是啥?
Rails 世界中是不是有与 ASP.NET Web API 等效的工具?
通过 IIS ARR 的客户端关联/粘性会话是不是适用于 ASP.NET Core 3+/.NET 5?