如何使用ASP.NET Core下载PNG文件

3

我需要让用户能够从我的网站下载PNG图片。当方法运行时,它会在没有错误的情况下完成,但不会下载任何图像。我不需要用户看到弹出对话框,尽管这肯定很有帮助。这是我现在的代码:

public async Task<IActionResult> DownloadImage(string filename)
        {
            var path = Path.GetFullPath("./wwwroot/images/school-assets/" + filename);
           MemoryStream memory = new MemoryStream();
            using (FileStream stream = new FileStream(path, FileMode.Open))
            {
                await stream.CopyToAsync(memory);
            }
            memory.Position = 0;
            return File(memory, "image/png", "download");
        }

这个方法由视图中的ajax调用触发,代码如下:

        $.ajax({
            url: "./MyHome/DownloadImage",
            type: "Get",
            data: {filename : filename},
            success: function (file) {
            },
            error: function (request, status, error) {
                console.log(request.responseText);
            }
        });
    }

编辑: 如果我在成功部分使用console.log file,我会看到一串字节,所以我知道它正在创建文件但不让用户访问它。我已经尝试过使用content disposition和创建物理文件结果的建议。


你是如何请求 DownloadImage 的?当你说没有图片下载时,是什么意思? - Edward
5个回答

2
<最初的回答> 对于File,您需要提供带有文件扩展名的文件名,否则下载的文件将无法打开。 尝试类似以下方式:
public async Task<IActionResult> DownloadImage(string filename)
{
    var path = Path.GetFullPath("./wwwroot/images/school-assets/" + filename);
    MemoryStream memory = new MemoryStream();
    using (FileStream stream = new FileStream(path, FileMode.Open))
    {
        await stream.CopyToAsync(memory);
    }
    memory.Position = 0;
    return File(memory, "image/png", Path.GetFileName(path));
}

我已经在视图中使用ajax调用来创建了这个。当它运行时,我可以将结果打印到控制台并查看字节字符串,但没有图像对话框弹出以下载它。以下是ajax示例。function DownloadImage(filename) { $.ajax({ url: "./MyHome/DownloadImage", type: "Get", data: {filename : filename}, success: function (file) { }, error: function (request, status, error) { console.log(request.responseText); } }); } - Caleb
@Caleb 如果你想通过ajax下载文件,你需要实现点击事件,请参考使用.Net Core 2和EPPlus下载Excel文件 - Edward
谢谢,我上班后会尝试这个。如果有效,我会告诉你答案。 - Caleb

1

您需要设置内容配置类型以启用文件的直接下载:

public IActionResult OnGetPng()
{
    var bytes = System.IO.File.ReadAllBytes("test.png");

    var cd = new System.Net.Mime.ContentDisposition
    {
        FileName = "test.png",
        Inline = false
    };

    Response.Headers.Add("Content-Disposition", cd.ToString());
    Response.Headers.Add("X-Content-Type-Options", "nosniff");

    return File(bytes, "image/png");

}

如果您喜欢,也可以使用 PhysicalFileResult 类型来处理流并从控制器返回 FileResult。在这种情况下,您的代码如下:

   var fn = Path.Combine(env.WebRootPath, "test.png");

   var contentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");

   Response.Headers[HeaderNames.ContentDisposition] = contentDisposition.ToString();

   return new PhysicalFileResult(fn, "image/jpeg");

要访问WebRootPath,您需要将IHostingEnvironment env注入到构造函数中。

0

这段代码可以将来自URL地址的照片保存到服务器文件夹中。

private readonly Lazy<HttpClient> _client;

在构造函数中:

_client = new Lazy<HttpClient>(() => clientFactory.CreateClient());

最好的方法是使用延迟加载,这样服务器就不需要立即创建HttpClient来消耗额外的资源。
public async Task<string> SavePhotoInFolder(string url)
        {
            string photoPath = $"/Photos/{Guid.NewGuid()}.jpeg";

            using (var request = new HttpRequestMessage(HttpMethod.Get, url))
            using (
                Stream contentStream = await (await _client.Value.SendAsync(request)).Content.ReadAsStreamAsync(),
                stream = new FileStream($"{_appEnvironment.WebRootPath}{photoPath}", FileMode.Create))
            {
                
                await contentStream.CopyToAsync(stream);
            }

            return photoPath;
        }

0

从下面的代码中,您可以下载png文件。

从文件夹下载png文件

[HttpGet]
        public FileStreamResult DownloadPngFile(string fileName)
        {            
            var stream = new FileStream(Directory.GetCurrentDirectory() + "\\wwwroot\\images\\school-assets\\" + fileName, FileMode.Open);
            return new FileStreamResult(stream, "image/png");
        }

从数据库下载png文件
   [HttpGet]
            public FileStreamResult DownloadPngFileFromDataBase(string id)
            {
                var _fileUpload = _db.ImageFileUpload.SingleOrDefault(aa => aa.fileid == id);         
                // _fileUpload.FileContent column type is byte
                MemoryStream ms = new MemoryStream(_fileUpload.FileContent);
                return new FileStreamResult(ms, "image/png");
            }

更多信息请参见此问题和答案。在asp.net core中下载Pdf文件(已接受的答案)以及一个额外的链接在asp.net core中下载文件


-1
你可以使用 HttpClient。
  using (var client = new HttpClient())
           {  
              try
              {
                using var result = await client.GetAsync($"http://{url}"); 
                if (result.IsSuccessStatusCode)
                {                        
                    return await result.Content.ReadAsByteArrayAsync();
                }

              }
             catch(Exception ex)
              {
                  Console.WriteLine(ex.InnerException);
              }
        } 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接