Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么Web API函数的GET请求没有返回我的文件?_C#_.net_Rest_Asp.net Web Api - Fatal编程技术网

C# 为什么Web API函数的GET请求没有返回我的文件?

C# 为什么Web API函数的GET请求没有返回我的文件?,c#,.net,rest,asp.net-web-api,C#,.net,Rest,Asp.net Web Api,我有一个可以通过REST API访问的函数,配置了ASP.NET Web API 2.1,该函数应该向调用者返回一个映像。出于测试目的,我只是让它返回我现在存储在本地机器上的示例图像。方法如下: public IHttpActionResult GetImage() { FileStream fileStream = new FileStream("C:/img/hello.jpg", FileMode.Open); HttpCon

我有一个可以通过REST API访问的函数,配置了ASP.NET Web API 2.1,该函数应该向调用者返回一个映像。出于测试目的,我只是让它返回我现在存储在本地机器上的示例图像。方法如下:

public IHttpActionResult GetImage()
        {
            FileStream fileStream = new FileStream("C:/img/hello.jpg", FileMode.Open);
            HttpContent content = new StreamContent(fileStream);
            content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/jpeg");
            content.Headers.ContentLength = fileStream.Length;
            return Ok(content);
         }
当这个方法被调用时,我根本没有得到一个图像。以下是我收到的答复:

{“Headers”:[{“Key”:“Content Type”,“Value”:[“image/jpeg”]},{“Key”:“Content Length”,“Value”:[“30399”]}


为什么我不能将图像数据作为请求的一部分取回?如何解决这个问题?

一种可能是编写一个自定义的
IHttpActionResult
来处理图像:

public class FileResult : IHttpActionResult
{
    private readonly string filePath;
    private readonly string contentType;

    public FileResult(string filePath, string contentType = null)
    {
        this.filePath = filePath;
        this.contentType = contentType;
    }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        return Task.Run(() =>
        {
            var response = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StreamContent(File.OpenRead(filePath))
            };

            var contentType = this.contentType ?? MimeMapping.GetMimeMapping(Path.GetExtension(filePath));
            response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);

            return response;
        }, cancellationToken);
    }
}

除了@Darin提到的内容之外,您正在使用的
Ok(T content)
帮助程序实际上返回一个
OkNegotiatedContentResult
,正如名称所示,它运行内容协商。由于在这种情况下不希望进行内容协商,因此需要创建自定义操作结果

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

您可以通过以下代码下载您的文件:

    HttpResponse response = HttpContext.Current.Response; 
    response.Clear();
    response.Buffer = false;
    response.BufferOutput = false;
    response.Charset = "UTF-8";
    response.ContentEncoding = System.Text.Encoding.UTF8;           
    response.AppendHeader("Content-disposition", "attachment; filename=" + fileName);
    response.Write(excelXml);
    response.Flush();
    response.End();
    HttpContext.Current.Response.End();

您可以使用以下代码从web api下载文件:

 HttpResponseMessage objResponse = Request.CreateResponse(HttpStatusCode.OK);               
 objResponse.Content = new StreamContent(new FileStream(HttpContext.Current.Server.MapPath("~/FolderName/" + FileName), FileMode.Open, FileAccess.Read));
 objResponse.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
 objResponse.Content.Headers.ContentDisposition.FileName = FileName;
 return objResponse;

为什么他们不能提供这个现成的?!是否需要运行
任务?
Task.FromResult
就够了吗?@Squidward虽然Task.FromResult可以工作,但我相信Task.Run在这种情况下可能更有用,因为它允许在单独的任务中读取文件。Task.Run也接受cancellationToken,因此这可能也有一些好处。@Scott如果代码速度快(调用两个构造函数),那么在基础结构上损失的CPU时间就比释放线程时间多。
 HttpResponseMessage objResponse = Request.CreateResponse(HttpStatusCode.OK);               
 objResponse.Content = new StreamContent(new FileStream(HttpContext.Current.Server.MapPath("~/FolderName/" + FileName), FileMode.Open, FileAccess.Read));
 objResponse.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
 objResponse.Content.Headers.ContentDisposition.FileName = FileName;
 return objResponse;