Web Api - 如何检测响应何时完成发送

Geo*_*uer 10 asp.net asp.net-web-api

在web api方法中,我正在生成一个文件,然后将其流式传输到响应中

public async Task<HttpResponseMessage> GetFile() {
    FileInfo file = generateFile();
    var msg = Request.CreateResponse(HttpStatusCode.OK);

    msg.Content = new StreamContent(file.OpenRead());
    msg.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
    msg.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") {FileName = file.Name};

    return msg;
}
Run Code Online (Sandbox Code Playgroud)

因为这是一个生成的文件,我想在响应完成流后删除它,但我似乎无法在管道中为此找到一个钩子.

我想我可以在静态中引用该文件,并设置一个自定义MessageHandler,它从同一个静态变量中提取值并删除.然而,这似乎不可能是因为使用静态(当这应该是每个请求时)并且因为我必须注册一个单独的路由.

我已经看到了这个问题,但似乎没有太多有用的回应.

Kir*_*lla 11

不错的场景!...使用消息处理程序的问题是响应写入发生在主机层和消息处理程序层下面,所以它们并不理想......

以下是如何做到这一点的示例:

msg.Content = new CustomStreamContent(generatedFilePath);
Run Code Online (Sandbox Code Playgroud)
public class CustomStreamContent : StreamContent
{
    string filePath;

    public CustomStreamContent(string filePath)
        : this(File.OpenRead(filePath))
    {
        this.filePath = filePath;
    }

    private CustomStreamContent(Stream fileStream)
        : base(content: fileStream)
    {
    }

    protected override void Dispose(bool disposing)
    {
        //close the file stream
        base.Dispose(disposing);

        try
        {
            File.Delete(this.filePath);
        }
        catch (Exception ex)
        {
            //log this exception somewhere so that you know something bad happened
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,您是否正在生成此文件,因为您正在将某些数据转换为PDF.如果是,那么我认为您可以PushStreamContent通过直接将转换后的数据写入响应流来实现此目的.这样您就不需要先生成文件,然后再担心删除它.