Reputation: 26058
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.
Upvotes: 1
Views: 403
Reputation: 1039588
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" }) %>
Upvotes: 2
Reputation: 9978
Making an .ashx
handler that BinaryWrite
s the content might help. Following is one way of achieving that:
STEP 1: Load
DataTable
(assuming that you have an ID column as well)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.DataBind
it to the GridView
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:
DataTable
using the IDAnd 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
Upvotes: 0