我正在使用Web API将大型文件流式传输到客户端,但我想记录下载是否成功。也就是说,如果服务器发送了文件的全部内容。
当HttpResponseMessage
完成发送数据时,是否有某种方法可以获得回调或事件?
也许是这样的:
var stream = GetMyStream();
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StreamContent(stream);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
// This doesn't exist, but it illustrates what I'm trying to do.
response.OnComplete(context =>
{
if (context.Success)
Log.Info("File downloaded successfully.");
else
Log.Warn("File download was terminated by client.");
});
答案 0 :(得分:3)
我不确定是否有直接信号表明一切正常,但您可以使用技巧在结束之前以及完全发送文件之后发现连接存在。
例如,如果客户端仍然连接,Response.IsClientConnected
将返回true,因此您可以检查以下内容:
// send the file, make a flush
Response.Flush();
// and now the file is fully sended check if the client is still connected
if(Response.IsClientConnected)
{
// log that all looks ok until the last byte.
}
else
{
// the client is not connected, so maybe have lost some data
}
// and now close the connection.
Response.End();
答案 1 :(得分:3)
我继承了StreamContent
并添加了我自己的OnComplete
操作来检查异常:
public class StreamContentWithCompletion : StreamContent
{
public StreamContentWithCompletion(Stream stream) : base (stream) { }
public StreamContentWithCompletion(Stream stream, Action<Exception> onComplete) : base(stream)
{
this.OnComplete = onComplete;
}
public Action<Exception> OnComplete { get; set; }
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
var t = base.SerializeToStreamAsync(stream, context);
t.ContinueWith(x =>
{
if (this.OnComplete != null)
{
// The task will be in a faulted state if something went wrong.
// I observed the following exception when I aborted the fiddler session:
// 'System.Web.HttpException (0x800704CD): The remote host closed the connection.'
if (x.IsFaulted)
this.OnComplete(x.Exception.GetBaseException());
else
this.OnComplete(null);
}
}, TaskContinuationOptions.ExecuteSynchronously);
return t;
}
}
然后我像这样使用它:
var stream = GetMyStream();
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StreamContentWithCompletion(stream, ex =>
{
if (ex == null)
Log.Info("File downloaded successfully.");
else
Log.Warn("File download was terminated by client.");
});
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
return response;
答案 2 :(得分:1)
如果服务器发送了文件的全部内容
实际上无事可做:)
这可能听起来非常简单,但您会知道是否引发了异常 - 如果您关心服务器交付而不是客户端中途取消。 IsClientConnected
基于ASP.NET HttpResponse
,而不是WebApi。