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;
}
}
首先,除了锁定您不想要的文件之外,我没有看到您启动的进程实现的任何有用功能。
请尝试删除这些行并重试。
.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 类型,否则最好将其保留为二进制数据。