How to add a file attachment to the Response when the file path is a URI in MVC.NET Actions?
I have a URL to a file, "http://mydomain.domain.com/files/somefile.mp3".
I also have an Action in my Controller.
I want the action to return the file as an attachm开发者_Go百科ent.
I know I can do this:
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName)
Response.AddHeader("Content-Length", lenOfFile)
Response.ContentType = "application/octet-stream"
But does that mean that the return type of the Action is void? And then what do I call to tell it to send?
I also tried:
return File(new FileStream(a.AssetPath, FileMode.Open), "application/octet-stream");
when the return type of the Action was FileStreamResult but it did not like the fact that my path was a URL.
Maybe with one of the sub classes of FileResult -> http://msdn.microsoft.com/en-us/library/system.web.mvc.fileresult.aspx
If non of the built-in work, you can write your own actionresult, with just the code you posted.
ps. random ActionResult example from a quick search
I would suggest writing your own ActionResult, like this:
public class FileUriResult : ActionResult
{
private string _contentType;
private string _fileUri;
private long _fileLength;
public FileUriResult(string contentType, string fileUri, long fileLength)
{
_contentType = contentType;
_fileUri = fileUri;
_fileLength = fileLength;
}
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
HttpResponseBase response = context.HttpContext.Response;
response.ContentType = _contentType;
response.AddHeader("Content-Disposition", "attachment; filename=" + _fileUri);
response.AddHeader("Content-Length", _fileLength.ToString();
}
}
Then just use it in your action method:
return new FileUriResult("application/octet-stream", a.AssetPath, lenOfFile);
What you needed was to use a WebRequest
to get the file and then use FileResult
to give it back to the client.
public static FileResult FileWebRequest(this Controller controller, Uri uri,
string contentType)
{
return controller.FileWebResult(uri, contentType, null);
}
public static FileResult FileWebResult(this Controller controller, Uri uri,
string contentType, string fileDownloadName)
{
WebRequest request = WebRequest.Create(uri);
using (WebResponse response = request.GetResponse())
{
byte[] buffer = new byte[response.ContentLength];
using (Stream responseStream = response.GetResponseStream())
using (MemoryStream memStream = new MemoryStream())
{
int bytesRead;
int totalBytesRead = 0;
while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
{
memStream.Write(buffer, totalBytesRead, bytesRead);
}
FileResult result = new FileContentResult(memStream.ToArray(), contentType);
if (fileDownloadName != null) {
result.FileDownloadName = fileDownloadName;
}
return result;
}
}
}
Then to use you just call like this from your controller:
return this.FileWebResult(new Uri("http://mydomain.domain.com/files/somefile.mp3"),
"application/octet-stream", fileName);
精彩评论