Add a hyperlink to grid column - c#

I'd like to have a link on the FileName column, so users can click and open a PDF file (no download, only open to view). This is what I have tried, but I don't know how to pass the file name to the server function.
columns.Bound(p => p.FileName)
.ClientTemplate( "/#= FileName #")
The FileHelper.GetFullPath method is a server function to generate the full path for the file. The full path should be:
http://servername/applicationname/filefolders/filename.pdf

You can't implement the PDF download on the client-side easily. You should instead stream the PDF file using another action method.
Try this instead:
.ClientTemplate("<a href='" + Url.Action("GetPdf", "Home") + "?fileName=#= FileName #'>#=FileName#</a>");
public ActionResult GetPdf(string fileName)
{
string path = FileHelper.GetFullPath(fileName);
FileStream stream = new FileStream(path, FileMode.Open);
return File(stream, "application/pdf", fileName + ".pdf");
}

Related

ASP .NET Core Web API - Getting and extracting a .zip file from upload controller, using IFormFile

I have an API Upload Controller, which has a parameter IFormFile. From Swagger, I am passing a .zip file which has a few .json files inside. I want to get these .json files from that .zip that I receive from Swagger and pass them to a service that will process them.
So I managed to create a logic like this. I save the .zip file in (~Temp>settings) directory, the next thing I want to do is unzip that file and send the .json files into a different directory named "temp-json-imports". So then I can get the .json files and work with them.
Here is the code that I have written so far, this doesn't work, it fails on the last line - (ZipFile.ExtractToDirectory(filePath, tmpJsonImports);), with an exception of type System.IO.IOException (like shown in the picture below).
Any ideas on how can I solve this problem would be very much welcome. :)
[HttpPost("import/{applicationId}")]
public async Task<IActionResult> ImportSettings([FromRoute] Guid applicationId, IFormFile file)
{
string tempPath = Path.Combine(_hostingEnvironment.ContentRootPath, Path.GetTempPath());
string tmpSettingsPath = Path.Combine(tempPath, "settings");
string tmpImportSettings = Path.Combine(tmpSettingsPath, "import");
string tmpJsonImports = Path.Combine(tmpImportSettings, "temp-json-imports");
Directory.CreateDirectory(tmpSettingsPath);
Directory.CreateDirectory(tmpImportSettings);
Directory.CreateDirectory(tmpJsonImports);
long size = file.Length;
if (size > 0)
{
var filePath = tmpImportSettings + "\\" + file.FileName;
using var stream = new FileStream(filePath, FileMode.Create);
await file.CopyToAsync(stream);
string zipPath = Path.GetFileName(filePath);
ZipFile.ExtractToDirectory(filePath, tmpJsonImports);
}
return Ok();
}
Try to use your code on my application, it will show this exception:
This exception relates the following code, you didn't close the file handle after copy the file to the path.
var filePath = tmpImportSettings + "\\" + file.FileName;
using var stream = new FileStream(filePath, FileMode.Create);
await file.CopyToAsync(stream);
To solve this exception, try to modify your code as below:
if (size > 0)
{
var filePath = tmpImportSettings + "\\" + fileviewmodel.File.FileName;
using (var stream = new FileStream(filePath, FileMode.Create))
{
await fileviewmodel.File.CopyToAsync(stream);
};
string zipPath = Path.GetFileName(filePath);
ZipFile.ExtractToDirectory(filePath, tmpJsonImports);
}

ASP.net download file Using HttpContext.Current.Response fileName

I am trying to download a file using System.Web.HttpContext.Current.Response using the following code:
HttpResponse objResponse = System.Web.HttpContext.Current.Response;
I am encoding the file name using:
FileName = Uri.EscapeDataString(FileName);
The file is downloading correctly, except when I have comma or dot in the file name.
In that case, while downloading the file, the explorer cannot decode the comma back.
For instance:
Original file name: Testing, File
Encoded name: Testing%2C%20file
Downloaded file name: Testing%2C file
Is there any way to code/encode the file name, in order to keep the commas and dots?
for example, you can use:
public ActionResult DownloadFileXML(string filePath)
{
string fileName = Path.GetFileName(filePath);
return File(filePath, "application/xml", fileName);
}

Open PDF file with Save As option in asp.net webform

I have list of PDF files on website (asp.net webforms). i want to open them with Save As option rather than it downlaods directly.
I tried to add download property to the link which didn't work. only was around seems to be HTTPHandler for *.pdf request.
I saw a piece of code for MVC based example here
return new FileStreamResult(stream, "application/pdf")
{
FileDownloadName = "file.pdf"
};
How can i convert this to HTTPHandler in as.net webform so that it open pdf files with Save As option.
I want to do it in a way so that when ever user click on any pdf file at that time Handler should come into action.
OR
I can create another file handlePDF.aspx and write code there also and will change link of pdf file to below
File One
If what you are trying to do is when they click on the file download link it pops up with save as or open dialog box, this is to do with the user's browser configuration. In the case of PDF's i believe Firefox has open in tab as the default option. If you try to push the file as a file stream it will more than likely just load it in a new tab as well.
tl;dr: Client side issue
You're on the right track. Serving PDF files are usually handled by an HttpHandler. That is, unless they can be served straight from the file system by the StaticHandler...
The key thing that is needed in order for the browser to raise the "Open or save" dialog is the Content-Disposition header in the response.
Here is an (untested) implementation that should get you on the right track:
public void ProcessRequest(HttpContext context)
{
string fileName = context.Request.QueryString["file"];
if(fileName == null || fileName == "")
{
throw new ArgumentException("The file argument cannot be null or empty");
}
// fetch file here from db/filesystem/other storage
byte[] fileBytes = LoadFileBytes(fileName);
context.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
context.Response.ContentType = "application/pdf";
context.Response.BinaryWrite(fileBytes);
}
If you want to avoid buffering the whole file in memory, this might also work (requires .Net 4.0 for the CopyTo method on the stream):
public void ProcessRequest(HttpContext context)
{
string fileName = context.Request.QueryString["file"];
if(fileName == null || fileName == "")
{
throw new ArgumentException("The file argument cannot be null or empty");
}
// fetch file stream from db/filesystem/other storage
Stream fileStream = GetFileStream(fileName);
context.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
context.Response.ContentType = "application/pdf";
fileStream.CopyTo(context.Response.OutputStream);
}

How to download a file using FileResult?

I have a list in my view with an ActionLink button 'Download' and I want them to download a file when they click the link. The file is located in a map in my project.
View:
<div id="right-column-links">
<h2>Your active links</h2>
#if (lstLinks.Count == 0)
{
<p>You have no active links yet.</p>
}
else
{
<table>
#foreach (var item in lstLinks)
{
<tr>
<td>#Html.DisplayFor(model => item.Url)</td>
<td>#Html.ActionLink("Put inactive", "LinkInActive", new { linkid=item.LinkId }, new { onclick = "return confirm('Are you sure you want this link inactive?');" })</td>
<td>#Html.ActionLink("Download Qrcode", "DownloadQrcode", new { linkid=item.LinkId })</td>
</tr>
}
</table>
}
</div>
Controller:
[HttpPost]
public FileResult DownloadQrcode(int linkid)
{
Qrcode Qrcode = DbO.getQrcodebyLinkId(linkid);
string image = Server.MapPath("~") + "\\Qrcodes\\" + Qrcode.Image;
string contentType = "image/jpg";
return File(image, contentType, "Qrcode-" + Qrcode.QrcodeId);
}
The linkid comes from the selected link in the list. Then I lookup what qrcode matches the linkid in my database. From this qrcode object I get the image name. Example (qrcode-1337). Then I'am not sure what to do. I lookup the path where my project is stored and attach the map Qrcodes to it (where all the images are stored) and the image name. This returns me a link that he doesn't find.
Map location:
C:\Users\stage\Desktop\Immo-QR\Immo-QR\Immo-QR\Qrcodes
This doesn't seem to work. I am not sure how I should use FileResult. Can anyone explain this? Or show me another way?
EDIT:
A user suggested me to put the images in the App_Data file which I did under a map Qrcodes.
To save the file I use this code:
string path = Server.MapPath("~");
System.IO.File.WriteAllBytes(path + "\\App_Data\\Qrcodes\\qrcode-" + qrcodeid + ".jpg", bytes);
If I use "~\App_Data\Qrcodes\qrcode-" instead of the above, It doesn't work either.
I still get this error: Server Error in '/' Application. The resource cannot be found.
SOLUTION:
With this code it works!
public FileStreamResult DownloadQrcode(int linkid)
{
Qrcode Qrcode = DbO.getQrcodebyLinkId(linkid);
string path = Server.MapPath("~");
Stream image = new FileStream(path + "\\App_Data\\Qrcodes\\" + Qrcode.Image + ".jpg", FileMode.Open);
return File(image, "image/jpeg");
}
Try changing your string image line to Stream image.
This will help understand if you can't read the file. Your return File line will take a Stream with no issues.
Your approach is correct.
I think the path to the file is incorrect.
If you use ~\\Qrcodes\\filename it will translate to <appRootDirectory>\\QrCodes\\filename.
Also remember that IIS runs as a separate user in most cases, which does not have a home directory like a regular user.
I would suggest you move the Qrcodes to AppData folder or AppGlobalResources folder.
If you dont want to do that, you need to provide absolute path to Qrcodes folder.

MVC C# Download file and save as dialog

Hi all wondering if someone can help; i've written this code which will generate an excel spreadsheet and save it to a specified location. I want to then display a "Save as" dialogue box by reading the file from the stored location and then asking then user where they want to store it. The excel file is being generated fine and i can open it normally! However my problem is the code i've written seems to be outputting the file directly to my browser, so i get all the contents of the excel file on my browser screen, not displaying the save as dialogue box as expected!
public ActionResult FormSuccess()
{
String FileName = System.Configuration.ConfigurationManager.AppSettings["FileName"].ToString();
String FilePath = System.Configuration.ConfigurationManager.AppSettings["FileSaveLocation"].ToString();
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "application/vnd.xls";
response.AddHeader("Content-Disposition", "attachment; filename=" + FileName + ";");
response.TransmitFile(FilePath + FileName);
response.End();
return PartialView("FormSuccess");
}
Yo Vince, how's tricks? Still wearing the medallion? :)
Shouldn't you be using FileContentResult instead of PartialView? You won't be able to return the file AND the HTML "success" content in the same call - you should probably call the PartialView first, which would then use javascript to open the FileContentResult URL in a new window.
See this: http://www.mikesdotnetting.com/Article/125/ASP.NET-MVC-Uploading-and-Downloading-Files
and this url as well :
http://weblogs.asp.net/rajbk/archive/2010/05/03/actionresult-types-in-mvc2.aspx
I think that your problem is that you return PartialView. Let me give you small exmaple of my implemetation:
public ActionResult FileXls()
{
var output = new MemoryStream();
var writer = new StreamWriter(output);
//create your workbook excel file
....
//workbook.Save(output);
writer.Flush();
output.Position = 0;
return File(output, "text/excel", "file.xls");
}

Categories