MVC 从 API 下载文件并重新调整

本文关键字:新调整 调整 API 下载 文件 MVC | 更新日期: 2023-09-27 18:37:15

我需要通过MVC操作方法传递文件。从 Web API 方法下载它并作为结果返回它。

我拥有的代码是由 SO 上的一些答案和其他一些参考资料组装而成的。

问题是当我尝试返回文件时,该文件似乎被下载过程锁定。我以为啧啧。Wait() 会解决这个问题。

也许有人知道更好的解决方案?

using (var client = HttpClientProvider.GetHttpClient())
{
    client.BaseAddress = new Uri(baseAddress);
    await client.GetAsync("api/Documents/" + fileName).ContinueWith(
    (requestTask) =>
    {
        HttpResponseMessage response = requestTask.Result;
        response.EnsureSuccessStatusCode();
        fileName = response.Content.Headers.ContentDisposition.FileName;
        if (fileName.StartsWith("'"") && fileName.EndsWith("'""))
        {
            fileName = fileName.Trim('"');
        }
        if (fileName.Contains(@"/") || fileName.Contains(@"'"))
        {
            fileName = Path.GetFileName(fileName);
        }
        path = Path.Combine(GetDocsMapPath(), fileName);
        System.Threading.Tasks.Task  tsk = response.Content.ReadAsFileAsync(path, true).ContinueWith(
        (readTask) =>
        {
            Process process = new Process();
            process.StartInfo.FileName = path;
            process.Start();
        });
        tsk.Wait();
        HttpResponseMessage resp = new HttpResponseMessage(HttpStatusCode.OK);
        resp.Content = new StreamContent(new FileStream(path, FileMode.Open, FileAccess.Read));
        resp.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
        resp.Content.Headers.ContentDisposition.FileName = fileName;
        return resp;
    });
}

        public static Task ReadAsFileAsync(this HttpContent content, string filename, bool overwrite)
        {
            string pathname = Path.GetFullPath(filename);
            if (!overwrite && File.Exists(filename))
            {
                throw new InvalidOperationException(string.Format("File {0} already exists.", pathname));
            }
            FileStream fileStream = null;
            try
            {
                fileStream = new FileStream(pathname, FileMode.Create, FileAccess.Write, FileShare.None);
                return content.CopyToAsync(fileStream).ContinueWith(
                     (copyTask) =>
                     {
                         fileStream.Close();
                         fileStream.Dispose();
                     });
            }
            catch
            {
                if (fileStream != null)
                {
                    fileStream.Close();
                    fileStream.Dispose();
                }
                throw;
            }
        }

MVC 从 API 下载文件并重新调整

首先,除了锁定您不想要的文件之外,我没有看到您启动的进程实现的任何有用功能。

请尝试删除这些行并重试。

.ContinueWith(
(readTask) =>
{
   Process process = new Process();
   process.StartInfo.FileName = path;
   process.Start();
});

编辑:使用FilePathResult

我不知道你的确切要求,但如果你的目标是返回一个你有路径的文件;那么最简单的是返回一个FilePathResult,它将负责读取文件的内容并将其返回给请求者。

public FilePathResult GetFile()
{
    //put your logic to determine the file path here
    string name = ComputeFilePath();
    //verify that the file actually exists and retur dummy content otherwise
    FileInfo info = new FileInfo(name);
    if (!info.Exists)
    {
        using (StreamWriter writer = info.CreateText())
        {
            writer.WriteLine("File Not Found");
        }
    }
    return File(name, "application/octet-stream");
}

如果您确定您的内容是什么类型,请相应地更改 MIME 类型,否则最好将其保留为二进制数据。