我有一个数据库,它将PDF文档作为字节流存储在varbinary(max)列中。原始文档名称存储在varchar列中,文档扩展名为主键,主键为guid。 (此架构已修复,文档必须驻留在数据库中)
将文档作为流检索并写入临时文件或直接流式传输到Web浏览器没有问题。
我的问题是如何通过Url使用原始文件名来公开文档?
我正在尝试做的一个很好的例子是SharePoint,在幕后,SharePoint将文件存储在SQL数据库中,并将文档公开为可以使用浏览器直接打开的Url(具有原始文件扩展名)。 / p>
例如:http://WebServer/Documents/MyDocument.pdf
(该平台是SQL 2008,IIS 7.5,.NET 4,C#)
答案 0 :(得分:4)
如果您的站点使用ASP.Net MVC,您只需按名称为/ Documents下载文件添加控制器:
routes.MapRoute(
"GetFiles",
"Documents/{fileName}",
new
{
controller = "Files",
action="GetFile",
}
);
和控制器类:
public class FilesController : Controller
{
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult GetFile(string fileName)
{...
}
}
答案 1 :(得分:2)
如果没有使用MVC,您可以使用名为IHttpHandler
的内容这将允许您以任何您喜欢的方式处理对URL的请求。 您将在web.config中添加代码,如下所示:
<httpHandlers>
<add verb="*" path="/documents/*.pdf" type="Documents.LoadDocument,NameSpace"/>
</httpHandlers>
然后你会有一个班级Namespace.Documents.LoadDocument
这实现了IHttpHandler接口(只有两个方法,其中一个只是一个bool,表明你的对象是否是线程安全的)
信息here描述了如何使用IHttpHandler提供动态内容。
我相信这正是你所寻找的。您将能够根据实际的http请求从数据库加载文档。
答案 2 :(得分:1)
您需要在回复中添加Content-Disposition
标题:
Content-Disposition: attachment; filename=original_name.pdf
答案 3 :(得分:1)
请参阅Download and Upload images from SQL Server via ASP.Net MVC以获取包含路由的完整示例,该路由将URL映射到数据库中的文件,使用流进行高效下载以及使用流进行高效上载。
路由部分相对简单,MVC:
routes.MapRoute(
"Media",
"Media/{filename}",
new { controller = "Media", action = "GetFile" },
new { filename = @"[^/?*:;{}\\]+" });
但其他的点点滴滴,特别是使用正确流式语义的上传,可能会比人们通常期望的要复杂一些。大多数示例都会忽略这些问题,并在将整个文件上传到数据库之前创建整个文件的内存副本。
跟进FILESTREAM MVC: Download and Upload images from SQL Server扩展了文章以涵盖FILESTREAM存储。