在Asp.Net Core 2中是否有与"HttpContext.Response.Write"等效的方法?

13

我正在尝试使用Asp.Net Core 2中的ActionFilter在页面上附加一些HTML和Javascript内容。

在MVC中,它可以这样工作:

 filterContext.HttpContext.Response.Write(stringBuilder.ToString());

但在核心部分它不起作用。

我尝试使用以下方式实现:

filterContext.HttpContext.Response.WriteAsync(stringBuilder.ToString());

但它会使整个页面变成空白。

我正在寻找 nopCommerce 4.0 的解决方案,它是基于 Asp.Core 2.0 构建的。

4个回答

19

目前,静态和异步方法HttpResponseWritingExtensions.WriteAsync是实现此目标的首选方式。

您可以在程序集 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();

来源:MSDN


10

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");} } *@ - dragansr

4
你可以尝试像这样做:
在自定义的INopStartup.Configure(IApplicationBuilder application)实现中。
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);
    }
}

结果如下:

结果HTML

希望这能帮助您找到正确的方法。


如果我们在nopCommerce中使用此解决方案,则会遇到问题。 在_INopStartup.Configure_方法中,如果我们首先调用await next()然后再还原响应流,它将无法在用户端加载图像和脚本,并给出响应Content-Length不匹配:写入了太多字节的错误。 如果我们首先恢复响应流,然后调用await next(),那么将在filterContext.HttpContext.Response.Body.Seek()方法未找到时出现错误。 - Raju Paladiya

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接