How to generate interchangeable download links? - asp.net-mvc

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;
}

Related

AspNet Core - Could not load the image from FileStreamResult

Please help.
I've been searching for hours now as I cannot display the image on the website. I'm using byte[] from database then return FileStreamResult in controller.
Below is my code
.cshtml
<img src="#Url.Action("GetImage", "User")" />
User Service
I was able to call the api with byte[] value.
public async Task<HttpResponseMessage> GetImage()
{
var client = _clientFactory.CreateClient("ApiName");
var response = await client.GetAsync(apiUrl);
return response;
}
Controller
[ResponseCache(Duration = 10)]
[HttpGet]
public async Task<IActionResult> GetImage()
{
var response = await _user.GetImage();
if (response.IsSuccessStatusCode)
{
var logo = await response.Content.ReadAsByteArrayAsync();
var ms = new MemoryStream(logo);
FileStreamResult result = new FileStreamResult(ms, "image/png");
result.FileDownloadName = "logo1223.png";
return result;
}
return null;
}
API
[HttpGet("logo")]
public async Task<IActionResult> GetImage()
{
var someByte= await GetSomeImage();
return Ok(someByte);
}
when I tried to download or save the image file I get this result.
Image is not loading from the website
UPDATE
I tried to manually get the file then convert to byte[] and image is displaying properly on the website,
I checked how they upload the image... I found out
they are using below code to save image on DB.
var byteArr= Encoding.UTF8.GetBytes(Convert.ToBase64String(bArr.ToArray()))
Tried this modified controller
public async Task<FileContentResult> GetImage()
{
var img = Image.FromFile(#"C:\Downloads\test.png");
byte[] bArr = imgToByteArray(img);
var a = Encoding.UTF8.GetBytes(Convert.ToBase64String(bArr.ToArray()));
return File(bArr, "image/png"); // WORKING!!!
//return File(a, "image/png"); // NOT WORKING!!
}
Is there a way to convert it to original byte image?
The main issue is logo is saved in db using below code
var byteArr= Encoding.UTF8.GetBytes(Convert.ToBase64String(bArr.ToArray()))
Solution: Convert to original byte[] to get the image
[ResponseCache(Duration = 10)]
[HttpGet]
public async Task<IActionResult> GetImage()
{
var response = await _user.GetImage();
if (response.IsSuccessStatusCode)
{
// I created new class Logo which contains byte[] Logo
var logo = await response.Content.ReadAsAsync<Logo>();
// Convert to original byte[]
byte[] originalByte = Convert.FromBase64String(Encoding.UTF8.GetString(logo.Logo));
return File(originalByte, "image/png");
}
return null;
}

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 download file in asp.net core

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
}
}

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