WebAPI returns corrupted, incomplete file

对着背影说爱祢 提交于 2020-08-07 07:44:09

问题


I want to return an image from WebApi endpoint. This is my method:

[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");
    }
}

Unfortunately, the file that is downloaded is incomplete. The message in consuming Android app is:

java.io.EOFException: source exhausted prematurely


回答1:


The problem is most likely that your Android client thinks the download is over before it actually is.
To easily fix this, you can use this method instead which will return the entire file at once (rather than streaming it):

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



回答2:


Turns out that this was caused by compression, that was set for all responses in this controller. There is GZip encoding set up in controller's constructor:

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

To solve this, I added these lines to my method (just after beginning of try block):

// 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;

Also, I'm setting content type and length like this:

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


来源:https://stackoverflow.com/questions/44925841/webapi-returns-corrupted-incomplete-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!