【问题标题】: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 解决方案

【问题讨论】:

    标签: c# asp.net-core asp.net-core-2.0 nopcommerce httpcontext


    【解决方案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

      【讨论】:

        猜你喜欢
        • 2018-06-16
        • 2017-06-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-09
        • 2018-04-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多