【问题标题】:ASP.NET Web API Controller output is always bufferedASP.NET Web API 控制器输出始终被缓冲
【发布时间】:2015-07-18 02:41:37
【问题描述】:

如何在没有缓冲的情况下发送输出?我这样定义了我的 API 控制器:

public class DefaultController : ApiController
{
    [HttpGet]
    [Route]
    public HttpResponseMessage Get()
    {
        var response = Request.CreateResponse();
        response.Content = new PushStreamContent(
            (output, content, context) =>
            {
                using (var writer = new StreamWriter(output))
                {
                    for (int i = 0; i < 5; i++)
                    {
                        writer.WriteLine("Eh?");
                        writer.Flush();
                        Thread.Sleep(2000);
                    }
                }
            },
            "text/plain");

        return response;
    }
}

输出会同时出现在浏览器中,因此看起来它会等待开始发送直到完成。我定义了这个属性:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
class NoBufferAttribute : Attribute, IControllerConfiguration
{
    public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor)
    {
        controllerSettings.Services.Replace(
            typeof(IHostBufferPolicySelector),
            new BufferPolicy());
    }

    class BufferPolicy : IHostBufferPolicySelector
    {
        public bool UseBufferedInputStream(object hostContext)
        {
            return false;
        }

        public bool UseBufferedOutputStream(HttpResponseMessage response)
        {
            return false;
        }
    }
}

并将其应用于控制器:

    [NoBuffer]
    public class DefaultController : ApiController
    {
          ...
    }

它没有帮助。所有输出同时出现在浏览器中。

更新

看起来问题与冲洗有关。我将代码更改为以下内容:

        var response = Request.CreateResponse();
        response.Content = new PushStreamContent(
            (output, content, context) =>
            {
                using (var writer = new StreamWriter(output))                    
                {
                    var s = Stopwatch.StartNew();
                    while (s.Elapsed < TimeSpan.FromSeconds(10))
                    {
                        writer.WriteLine(s.Elapsed);
                        writer.Flush();                            
                    }
                }
            },
            "text/plain");

现在我可以看到正在进行的输出。禁用 gzip 编码无助于查看更小块的内容。

【问题讨论】:

  • 这有帮助吗? stackoverflow.com/questions/25429726/… 好像一个请求头解决了这个人的问题。
  • 据我所知,他提到了客户端配置。我无法控制网络浏览器,但我看到浏览器在加载文本文件时会逐渐呈现它们。应该是关于服务器端的。
  • 但是您的请求是来自 ajax 帖子还是来自您控制的站点?如果是这样,您可以将标头添加到请求中。 stackoverflow.com/questions/7686827/…
  • 不,我没有客户端控制。自从旧的网络浏览器逐渐呈现文本文件以来。真的有必要在浏览器端进行任何调整吗?
  • this 帖子。

标签: c# asp.net-web-api asp.net-web-api2


【解决方案1】:

请为 PushStreamContent 构造函数的 mediaType 参数尝试“文本/事件流”:

public class DefaultController : ApiController
{
    [HttpGet]
    [Route]
    public HttpResponseMessage Get()
    {
        var response = Request.CreateResponse();
        response.Content = new PushStreamContent(
            (output, content, context) =>
            {
                using (var writer = new StreamWriter(output))
                {
                    for (int i = 0; i < 5; i++)
                    {
                        writer.WriteLine("Eh?");
                        writer.Flush();
                        Thread.Sleep(2000);
                    }
                }
            },
            "text/event-stream");

        return response;
    }
}

这对我有用(使用 .net 4.6.1)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-30
    • 1970-01-01
    • 2013-05-22
    • 2013-10-16
    • 2016-05-12
    相关资源
    最近更新 更多