How to download file in asp.net core - asp.net-mvc

My download method is
public async Task<IActionResult> Download(string filename)
{
if (filename == null)
return Content("filename not present");
var path = Path.Combine(
Directory.GetCurrentDirectory(), "wwwroot" + #"\UploadFiles", filename);
var memory = new MemoryStream();
using (var stream = new FileStream(path, FileMode.Open))
{
await stream.CopyToAsync(memory);
}
memory.Position = 0;
return File(memory, GetContentType(path), Path.GetFileName(path));
}
and view.chtml and route with filepath
<a asp-action="Download"
asp-route-filename="#item.UploadFilePath">
Download
</a>
#item.UploadFilePath is database saved path.please help me.

you can try this also
return File(path, MediaTypeNames.Application.Octet, Path.GetFileName(path));

You can try this,
byte[] fileBytes = System.IO.File.ReadAllBytes(Filepath);
return File(fileBytes, "application/x-msdownload", FileName);

use this code for download file from wwwroot
public IActionResult DownloadAttachment(string attachment)
{
var path = Path.Combine(
Directory.GetCurrentDirectory(), "wwwroot\\UploadFile\\Journal",attachment);
byte[] fileBytes = System.IO.File.ReadAllBytes(path);
return File(fileBytes, "application/x-msdownload", attachment);
}

Try this on URL /Files?fileName=image.png, file image.png must be placed in wwwroot.
public class FilesModel : PageModel
{
private readonly IWebHostEnvironment hostingEnvironment;
public FilesModel(IWebHostEnvironment hostingEnvironment)
{
this.hostingEnvironment = hostingEnvironment;
}
public PhysicalFileResult OnGet(string fileName)
{
string path = Path.Combine(hostingEnvironment.WebRootPath, "Files", fileName);
return new PhysicalFileResult(path, "image/png"); // Change to the right mime type
}
}

Related

How to change the PDF fileName to file Name as it display Function name as FileName in mvc

I wanted to display pdf file name as the filename but it display function name as file Name.Below is the set of code
public async Task<FileStreamResult> GetPDF(string FileName, string DocName)
{
CloudFile file = Utility.CloudAzureFile(DocName, FileName, ".pdf");
string Cloudfilename = file.Uri.ToString();
if (file.Exists())
{
var stream = await file.OpenReadAsync();
return File(stream, "application/pdf");
}
return null;
}
I have tried below two approaches to show but in both way it is opening an download dialoge box.
return File(stream, "application/pdf", FileName);
and
Response.AddHeader("Content-Disposition", "attachment; filename="+DocName);
//Response.AppendHeader("Content-Disposition", FileName.ToString());
return File(stream, "application/pdf");
Editied:
public async Task<FileStreamResult> GetPDF(string FileName, string DocName)
{
CloudFile file = Utility.CloudAzureFile(DocName, FileName, ".pdf");
string Cloudfilename = file.Uri.ToString();
if (file.Exists())
{
var stream = await file.OpenReadAsync();
var result = new FileStreamResult(stream, "application/pdf");
result=.FileDownloadName = FileName + ".pdf";
return result;
}
return null;
}
Try this piece of code this is working for me hope it help.

How to generate interchangeable download links?

i'm tying to make DL link so others couldn't dl the same file by sharing it
so far i've found this code
public FileResult Download()
{
byte[] fileBytes = System.IO.File.ReadAllBytes(#"c:\folder\myfile.ext");
string fileName = "myfile.ext";
return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}
it won't make interchangeable links ,how can we do that?
Try this Example:
public ActionResult Download()
{
var filePath=#"c:\folder\myfile.ext";
var fileBytes = System.IO.File.ReadAllBytes(filePath);
var response = new FileContentResult(fileBytes, "application/octet-stream")
{
FileDownloadName = Path.GetFileName(filePath)
};
return response;
}

Uploading and Viewing Photos

Can anyone help i'm using MVC 5 and doing a code on uploading and displaying photos and i'm having an error (The name ' file ' does not exist in the current content) please help
This is the controller i'm using:
public class UploadController : Controller
{
private DataContext db = new DataContext();
public ActionResult Index()
{
var model = new UploadViewModel();
return View(model);
}
[HttpPost]
public ActionResult Upload(UploadViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
UploadDbModel fileUploadModel = new UploadDbModel();
try
{
if (file.ContentLength > 0)
{
byte[] uploadFile = new byte[model.File.InputStream.Length];
model.File.InputStream.Read(uploadFile, 0, uploadFile.Length);
fileUploadModel.FileName = model.File.FileName;
fileUploadModel.File = uploadFile;
db.UploadDbModels.Add(fileUploadModel);
db.SaveChanges();
}
return Content("FILE SUCCESSFULLY UPLOADED");
}
catch
{
return Content("UPLOAD FAILED");
}
}
public ActionResult Download()
{
return View(db.UploadDbModels.ToList());
}
public FileContentResult FileDownload(int? id)
{
byte[] fileData;
string fileName;
UploadDbModel fileRecord = db.UploadDbModels.Find(id);
fileData = (byte[])fileRecord.File.ToArray();
fileName = fileRecord.FileName;
return File(fileData, "text", fileName);
}
}
In Asp.Net MVC we have to use HttpPostedFileBase for Uploaded files as shown below :-
[HttpPost]
public ActionResult Upload(UploadViewModel model, HttpPostedFileBase file)
{
if (file != null)
{
int byteCount = file.ContentLength; <---Your file Size or Length
.............
.............
}
}
Try and use system.web, just add the reference on the assembly hope it works.

How to route to static page with out change url path in asp.net mvc3

Basically,I'm trying to route to a static page like this:
http://127.0.0.1/mypage
=route to=>
A static page in my website folder maybe http://127.0.0.1/static/mypage.html
I have tried:
Add a route role:
routes.MapRoute("StaticPage", "{pagename}", new { controller = "Common", action = "StaticPage" });
Add an action in Common Controller:
public ActionResult StaticPage(string pagename)
{
return Redirect("/static/" + pagename + ".html");
}
But it will change the url and cause twice request, is there any other way(no iframe in view) to remain the url?
Write the file to the response and then return an EmptyResult.
public ActionResult StaticPage(string pagename)
{
Response.WriteFile(Url.Content(string.Format("/static/{0}.html", pagename)));
return new EmptyResult();
}
You could simply have your controller return the contents of the desired file like so:
public ActionResult StaticPage(String pageName) {
return Content(GetFileContents("/static/" + pageName + ".html"));
}
public static string GetFileContents(string FileName)
{
StreamReader sr = null;
string FileContents = null;
try
{
FileStream fs = new FileStream(FileName, FileMode.Open,
FileAccess.Read);
sr = new StreamReader(fs);
FileContents = sr.ReadToEnd();
}
finally
{
if(sr != null)
sr.Close();
}
return FileContents;
}

Using memorystream and DotNetZip in MVC gives "Cannot access a closed Stream"

I'm trying to create a zipfile in a MVC method using the DotNetZip components.
Here is my code:
public FileResult DownloadImagefilesAsZip()
{
using (var memoryStream = new MemoryStream())
{
using (var zip = new ZipFile())
{
zip.AddDirectory(Server.MapPath("/Images/"));
zip.Save(memoryStream);
return File(memoryStream, "gzip", "images.zip");
}
}
}
When I run it I get a "Cannot access a closed Stream" error, and I'm not sure why.
Don't dispose the MemoryStream, the FileStreamResult will take care once it has finished writing it to the response:
public ActionResult DownloadImagefilesAsZip()
{
var memoryStream = new MemoryStream();
using (var zip = new ZipFile())
{
zip.AddDirectory(Server.MapPath("~/Images"));
zip.Save(memoryStream);
return File(memoryStream, "application/gzip", "images.zip");
}
}
By the way I would recommend you writing a custom action result to handle this instead of writing plumbing code inside your controller action. Not only that you will get a reusable action result but bear in mind that your code is hugely inefficient => you are performing the ZIP operation inside the memory and thus loading the whole ~/images directory content + the zip file in memory. If you have many users and lots of files inside this directory you will very quickly run out of memory.
A much more efficient solution is to write directly to the response stream:
public class ZipResult : ActionResult
{
public string Path { get; private set; }
public string Filename { get; private set; }
public ZipResult(string path, string filename)
{
Path = path;
Filename = filename;
}
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
var response = context.HttpContext.Response;
response.ContentType = "application/gzip";
using (var zip = new ZipFile())
{
zip.AddDirectory(Path);
zip.Save(response.OutputStream);
var cd = new ContentDisposition
{
FileName = Filename,
Inline = false
};
response.Headers.Add("Content-Disposition", cd.ToString());
}
}
}
and then:
public ActionResult DownloadImagefilesAsZip()
{
return new ZipResult(Server.MapPath("~/Images"), "images.zip");
}
Couldn't comment.
Darin's answer is great! Still received a memory exception though so had to add response.BufferOutput = false; and because of that had to move content-disposition code higher.
So you have:
...
var response = context.HttpContext.Response;
response.ContentType = "application/zip";
response.BufferOutput = false;
var cd = new ContentDisposition
{
FileName = ZipFilename,
Inline = false
};
response.Headers.Add("Content-Disposition", cd.ToString());
using (var zip = new ZipFile())
{
...
Just in case it wasn't obvious :)

Resources