如何在不公开 URL 的情况下在 MVC 中提供文件?
How to serve a file in MVC without exposing the URL?
我有一个树状查看器,允许用户浏览文件和子目录,当用户到达文件时,网站将转到 https://website.com/path/subpath/file.pdf
。假设我可以识别用户正在查看文件,将发生以下情况:
- 控制器将生成一个 SAS 密钥以从 Azure 检索文件。
- 控制器会得到一个url:
https://myaccount.files.core.windows.net/path/?=accesskey
虽然用户查看此访问密钥没有问题,但它最终会过期,为了用户将页面添加为书签,我希望用户不是重定向到 Azure 路径,但 ASP.NET 输出文件,就好像用户仍在 https://website.com/path/subpath/file.pdf
所以最后的问题基本上是:
How can I output a file, without forcing download and without showing the file path/url?
您可以尝试从存储中读取文件作为字节数组,并使用 File
方法从操作方法中 return 它。
public ActionResult View(int id)
{
// id is a unique id for the file. Use that to get the file from your storage.
byte[] byteArrayOfFile=GetFileInByteArrayFormatFromId(id);
return File(byteArrayOfFile,"application/pdf");
}
假设 GetFileInByteArrayFormatFromId
returns 是从您的 storage/azure 读取后文件的字节数组版本。您可以考虑在您的环境中缓存一些文件,这样您就不需要在每次请求时都联系 Azure 来获取它。
如果您可以将文件作为文件流读取,File
方法也有一个重载
public ActionResult View(int id)
{
// id is a unique id for the file. Use that to get the file from your storage.
FileStream fileStream = GetFileStreamFromId(id);;
return File(fileStream, "application/pdf","Myfile.pdf");
}
如果您的服务器中有可用的文件(缓存文件),您可以使用另一个 File 方法重载,您将传递路径而不是字节数组。
public ActionResult View(int id)
{
var f = Server.MapPath("~/Content/Downloads/sampleFile.pdf");
return File(f,"application/pdf");
}
如果浏览器支持显示响应的内容类型,则响应将显示在浏览器中。大多数主流浏览器都支持渲染pdf文件。
还有一个 File 方法的重载,它采用浏览器 save/download 对话框将使用的下载文件名,以便用户可以将其保存到本地计算机 and/or 打开。
public ActionResult View(int id)
{
var pathToTheFile=Server.MapPath("~/Content/Downloads/sampleFile.pdf");
return File(pathToTheFile, MimeMapping.GetMimeMapping(pathToTheFile),"Myfile.pdf");
}
public ActionResult ViewFromByteArray(int id)
{
byte[] byteArrayOfFile=GetFileInByteArrayFormatFromId(id);
return File(byteArrayOfFile, "application/pdf","Myfile.pdf");
}
这样,用户将从浏览器收到下载提示。
我有一个树状查看器,允许用户浏览文件和子目录,当用户到达文件时,网站将转到 https://website.com/path/subpath/file.pdf
。假设我可以识别用户正在查看文件,将发生以下情况:
- 控制器将生成一个 SAS 密钥以从 Azure 检索文件。
- 控制器会得到一个url:
https://myaccount.files.core.windows.net/path/?=accesskey
虽然用户查看此访问密钥没有问题,但它最终会过期,为了用户将页面添加为书签,我希望用户不是重定向到 Azure 路径,但 ASP.NET 输出文件,就好像用户仍在 https://website.com/path/subpath/file.pdf
所以最后的问题基本上是:
How can I output a file, without forcing download and without showing the file path/url?
您可以尝试从存储中读取文件作为字节数组,并使用 File
方法从操作方法中 return 它。
public ActionResult View(int id)
{
// id is a unique id for the file. Use that to get the file from your storage.
byte[] byteArrayOfFile=GetFileInByteArrayFormatFromId(id);
return File(byteArrayOfFile,"application/pdf");
}
假设 GetFileInByteArrayFormatFromId
returns 是从您的 storage/azure 读取后文件的字节数组版本。您可以考虑在您的环境中缓存一些文件,这样您就不需要在每次请求时都联系 Azure 来获取它。
如果您可以将文件作为文件流读取,File
方法也有一个重载
public ActionResult View(int id)
{
// id is a unique id for the file. Use that to get the file from your storage.
FileStream fileStream = GetFileStreamFromId(id);;
return File(fileStream, "application/pdf","Myfile.pdf");
}
如果您的服务器中有可用的文件(缓存文件),您可以使用另一个 File 方法重载,您将传递路径而不是字节数组。
public ActionResult View(int id)
{
var f = Server.MapPath("~/Content/Downloads/sampleFile.pdf");
return File(f,"application/pdf");
}
如果浏览器支持显示响应的内容类型,则响应将显示在浏览器中。大多数主流浏览器都支持渲染pdf文件。
还有一个 File 方法的重载,它采用浏览器 save/download 对话框将使用的下载文件名,以便用户可以将其保存到本地计算机 and/or 打开。
public ActionResult View(int id)
{
var pathToTheFile=Server.MapPath("~/Content/Downloads/sampleFile.pdf");
return File(pathToTheFile, MimeMapping.GetMimeMapping(pathToTheFile),"Myfile.pdf");
}
public ActionResult ViewFromByteArray(int id)
{
byte[] byteArrayOfFile=GetFileInByteArrayFormatFromId(id);
return File(byteArrayOfFile, "application/pdf","Myfile.pdf");
}
这样,用户将从浏览器收到下载提示。