WebAPI返回损坏的,不完整的文件

时间:2017-07-05 12:07:09

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

我想从WebApi端点返回一个图像。这是我的方法:

[System.Web.Http.HttpGet]
public HttpResponseMessage GetAttachment(string id)
{
    string dirPath = HttpContext.Current.Server.MapPath(Constants.ATTACHMENT_FOLDER);
    string path = string.Format($"{dirPath}\\{id}.jpg");

    try
    {
        HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
        var stream = new FileStream(path, FileMode.Open, FileAccess.Read);

        var content = new StreamContent(stream);
        result.Content = content;
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = Path.GetFileName(path) };
        return result;
    }
    catch (FileNotFoundException ex)
    {
        _log.Warn($"Image {path} was not found on the server.");
        return Request.CreateResponse(HttpStatusCode.NotFound, "Invalid image ID");
    }
}

不幸的是,下载的文件不完整。使用Android应用的消息是:

  

java.io.EOFException:source earlyusted toocedly

2 个答案:

答案 0 :(得分:0)

问题很可能是您的Android客户端认为下载已经结束。实际上 要轻松解决这个问题,您可以使用此方法,它将立即返回整个文件(而不是流式传输):

result.Content = new ByteArrayContent(File.ReadAllBytes(path));

答案 1 :(得分:0)

原来这是由压缩引起的,该压缩是为此控制器中的所有响应设置的。在控制器的构造函数中设置了GZip编码:

HttpContext.Current.Response.AppendHeader("Content-Encoding", "gzip");
HttpContext.Current.Response.Filter = new GZipStream(HttpContext.Current.Response.Filter, CompressionMode.Compress);

为了解决这个问题,我将这些行添加到了我的方法中 (在try块开始之后):

// reset encoding and GZip filter
HttpContext.Current.Response.Headers["Content-Encoding"] = "";
HttpContext.Current.Response.Headers["Content-Type"] = "";    
// later content type is set to image/jpeg, and default is application/json
HttpContext.Current.Response.Filter = null;

另外,我设置内容类型和长度如下:

result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
result.Content.Headers.ContentLength = stream.Length;