Reputation: 2947
Problem: I have file named by their Id from database. And when somebody want to downaload it I need to change it to it's real name. File on the server looks for example like: http://localhost:34256/Content/uploads/23. So for example my file name is 23 but i need to change it to textfile1.txt.
I have created a partial view with list of those files:
@foreach (var item in Model)
{
<a href="/Content/uploads/@item.Id" title="@Html.Encode(item.FileName)">
<img src="@item.IcoSrc" /><br />
@item.FileName
</a>
}
Where @item.FileName
is real name of file. When somebody download file from this list, he get's file named @item.Id and not @item.FileName. How can I change it?
I am using MVC3 and .NET framevork 4.
Any help much appreciated!
Upvotes: 3
Views: 7805
Reputation: 1038740
You could create a controller action that will serve the file:
public ActionResult Download(string id, string name)
{
var file = Server.MapPath("~/Content/uploads/" + id);
return File(file, "application/octet-stream", name);
}
and then point the link to this controller action:
@foreach (var item in Model)
{
<a href="@Url.Action("Download", new { id = item.Id, name = item.FileName })" title="@Html.Encode(item.FileName)">
<img src="@item.IcoSrc" /><br />
@item.FileName
</a>
}
Upvotes: 8
Reputation: 38825
As Anders said, you need to use Content-Disposition
.
To do this, create a controller-derivative that has a method .e.g Download
, that takes the ID of the file. You can then read the ID (and obtain the original filename), and use the FileResult
class to deliver the file (you can set the filename using the FileDownloadName
property which will set the disposition for you.
Upvotes: 0
Reputation: 3965
Since you are using MVC you can create an action that returns a FileContentResult
.
Read this article for the details: http://www.mikesdotnetting.com/Article/125/ASP.NET-MVC-Uploading-and-Downloading-Files
The following snippet is extracted from that article. Notice that you can control the filename property:
public FileContentResult GetFile(int id)
{
SqlDataReader rdr; byte[] fileContent = null;
string mimeType = "";string fileName = "";
const string connect = @"Server=.\SQLExpress;Database=FileTest;Trusted_Connection=True;";
using (var conn = new SqlConnection(connect))
{
var qry = "SELECT FileContent, MimeType, FileName FROM FileStore WHERE ID = @ID";
var cmd = new SqlCommand(qry, conn);
cmd.Parameters.AddWithValue("@ID", id);
conn.Open();
rdr = cmd.ExecuteReader();
if (rdr.HasRows)
{
rdr.Read();
fileContent = (byte[])rdr["FileContent"];
mimeType = rdr["MimeType"].ToString();
fileName = rdr["FileName"].ToString();
}
}
return File(fileContent, mimeType, fileName);
}
Upvotes: 4
Reputation: 69260
You can't do it in the link to the file. You have to do it by setting a Content-Disposition
header in the response delivering the file back to the client.
See this SO post for more info: https://stackoverflow.com/q/3102276/280222
Upvotes: 1