Display uploaded document from database
I have 开发者_如何学运维a MVC 2 web application. The website captures grant applications for loans. With each application I can upload documents. The way that we upload documents to the database is as follows:
private IEnumerable<byte> GetStreamByteArrayData(Stream stream)
{
byte[] buffer = new byte[8192];
int bytesRead = 0;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
for (int byteIndex = 0; byteIndex < bytesRead; byteIndex++)
{
yield return buffer[byteIndex];
}
}
}
The calling method looks like this:
Convert.ToBase64String(GetStreamByteArrayData(hpf.InputStream).ToArray());
In my grid that displays the uploaded documents I have the document name, mime type and so forth. What I am trying to do is to have the name of the document in a link. When the link is clicked then the document is opened. I have no idea how to do this in an MVC app.
Can someone please advise or provide some sample source code? All help would be appreciated.
Thanks.
Assuming that you have stored the name, mime type and contents of each document into the database you could have a controller action which will serve a file given it's unique id:
public ActionResult Download(int? id)
{
Document document = _repository.GetDocument(id);
if (document == null)
{
throw new HttpException(404, "Not found");
}
// For example document.ContentType = "application/pdf" and
// document.Name = "test.pdf"
return File(document.Contents, document.ContentType, document.Name);
}
The Document model might look something like this:
public class Document
{
public int Id { get; set; }
public byte[] Contents { get; set; }
public string ContentType { get; set; }
public string Name { get; set; }
}
And finally you could generate links to this action in your grid:
<%: Html.ActionLink("Download", "Download", new { id = "123" })%>
If you don't have the content type and name of the document stored into the database you could pass them as action parameters:
<%: Html.ActionLink("Download", "Download",
new { id = "123", contentType = "application/pdf", name = "test.pdf" }) %>
Making an .ashx
handler that BinaryWrite
s the content might help. Following is one way of achieving that:
STEP 1: Load
- Load your data into the
DataTable
(assuming that you have an ID column as well) - Add a template item of type link in your markup
- Add a LINK column and set the records like
http://yourpath/ShowContent.ashx?ID=111
(for instance, Id is the primary key) by either going through each record or when saving the records in the database. - Set and
DataBind
it to theGridView
STEP 2: Display
Upon click on a link in the GridView, it shall call the ShowContent.ashx
; handle the event there and following shall happen:
- Get the event in ShowContent.ashx
- Get the value in the ID from query string
- Select that record from the
DataTable
using the ID And
BinaryWrite
something like following:byte[] content = (byte[])dataRow["COL_CONTENT"]; HttpContext.Current.Response.ContentType = dataRow["COL_CONTENT_TYPE"]; HttpContext.Current.Response.BinaryWrite(content);
Note that you may need to add your DataTable/records in the session for handy processing of records.
Enjoy the example, A Boilerplate HttpHandler
精彩评论