MVC json vs. ActionLink - asp.net-mvc

new to programming. I am trying to print a PDF from MVC, it works well if I use Action Link, here is my code:
<%= Html.ActionLink("Print","GeneratePdf","Home", new { fc="Test" },null) %>
public ActionResult GeneratePdf(string fc)
{
Document document = new Document();
MemoryStream workStream = new MemoryStream();
PdfWriter.GetInstance(document, workStream);
document.Open();
document.Add(new iTextSharp.text.Paragraph("\n\n"));
// need to add the user name
iTextSharp.text.Paragraph p = new iTextSharp.text.Paragraph("Name: " + fc);
p.Alignment = 1;
document.Add(p);
document.Close();
byte[] byteInfo = workStream.ToArray();
SendPdfToBrowser(byteInfo);
return null;
}
public void SendPdfToBrowser(byte[] buf)
{
string filename = "Certificate.pdf";
// Prepare the headers.
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
// Write the PDF data.
Response.BinaryWrite(buf);
// Flush the buffer to the browser.
Response.End();
Response.Flush();
Response.Clear();
}
I need to use Json, here is the code:
function PrintChart(fc) {
var fc = "Test";
var url = '<%= Url.Content("~/Home/GeneratePdf") %>';
$.post(url, { fc: fc },
function (content) {
if (content != null) { 5 }
}, "json");
<input type="button" onclick="PrintChart();" value="Print" />
I don't get any errors but it does not generate the PDF file. Thanks in advance.

You cannot use Ajax to download file. The jQuery $.post() will expect the response from the server is text.
To download file in a Ajax way, a general approach is to use a hidden iframe and set the src of the iframe to the URL of the file
<iframe id="hiddenFrame" src="" style="display:none; visibility:hidden;"></iframe>
In PrintChart() create URL including data as query-string and set the src of the iframe:
function PrintChart(fc) {
var fc = "Test";
var url = '<%= Url.Content("~/Home/GeneratePdf") %>';
url += "?fc="+fc;
$('#hiddenFrame').attr('src', url);
}

Related

I want to download my Pdf File in server path in mvc please any one guide me... with code

what is the controller code.
how can i set the path of the server folder.
string path = HttpContext.Server.MapPath("~/Areas/CreatePaperSet/PdfPaperSet");
HttpContext.Response.TransmitFile(path);
WebClient client = new WebClient();
byte[] buffer = client.DownloadData(path);
if (buffer != null)
{
Response.Clear();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=DownloadPaperSet.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.BinaryWrite(buffer);
Response.End();
}
pdfDoc.Close();
This is my way to download file in folder and it worked.
You can create an Action with fileName as parameter.
In action you read file as byte[] and return File object.
public ActionResult Download(string fileName)
{
string path = Server.MapPath("~/Content/PdfPaperSet");
byte[] fileBytes = System.IO.File.ReadAllBytes(path + #"\" + fileName);
return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}
In your cshtml file, pass fileName = "yourfile.pdf" as parameter.
#Html.ActionLink("Download Your File", "Download", new { fileName = "yourfile.pdf" })

Rest API, file generation on client side

I have an asp.net core website with a controller that return a View with a viewmodel.
This view generate a pdf on javascript using jsPdf. I can't perform the pdf generation on server side because i'm using a client side componnent (fabric.js)
I would like to expose an API to be able to download this pdf.
When i hit my end point with a browser, the pdf file is downloaded correctly.
When i'm using postman or a WebClient in c#, i can't get the pdf...
I guess i'm missing something. The Test method does not work, i have a pdf but i can't open it, it's only 15ko :(
My view :
<script src="/Scripts/fabric.js"></script>
<script src="/Scripts/jspdf.debug.js"></script>
<script type="text/javascript">
var canvas = new fabric.Canvas('canvas', {});
canvas.loadFromJSON(#Html.Raw(Model.Json),
() => {
canvas.setWidth(#Model.Width);
canvas.setHeight(#Model.Height);
var imgData = new Image();
imgData.crossOrigin = "Anonymous";
imgData.src = canvas.toDataURL('png');
var pdf = new jsPDF('p', 'pt', [#Model.Width, #Model.Height]);
pdf.addImage(imgData, 'PNG', 1, 1, #Model.Width, #Model.Height, 'Mockup', 'NONE', 0);
pdf.save('myMockup.pdf');
}
);
</script>
My controller :
public IActionResult Generate(int id)
{
var mockup = DynamicValueAppService.ParseMockup(id);
var mockupVM = new MockupGeneratorViewModel()
{
Width = mockup.Width,
Height = mockup.Height,
Json = JObject.Parse(mockup.Json)
};
Response.Headers.Add("Content-Type","application/octet-stream");
Response.Headers.Add("Content-Disposition", "attachment");
return View(mockupVM);
}
public IActionResult Test()
{
var client = new WebClient();
client.DownloadFile("http://localhost:21021/Mockup/generate/1", #"C:\mum.pdf");
return new EmptyResult();
}

MVC Image - Dispaly in a Tab instead of downloading to a file

I have the following controller method which gets a PNG from a web api.
public async Task<ActionResult> RealTimeUpdate(string fundName)
{
string docPath = ConfigurationManager.AppSettings["RealTimeUpdate"].Replace("{fundname}",fundName).ToString();
docPath = docPath.Replace("\\\\", "\\");
docPath = docPath.Replace("\"", "");
string url = ServiceUrl + "api/RealTime/" + fundName;
HttpResponseMessage response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var dataStream = response.Content.ReadAsStringAsync().Result;
if (dataStream == null)
return HttpNotFound();
var _buffer = JsonConvert.DeserializeAnonymousType(dataStream, new { _buffer = (byte[])null })._buffer;
// If user decides to save the file, this will help...
//Response.AddHeader("content-disposition", "filename=" + Path.GetFileName(path));
return File(_buffer, "application/png");
}
return View("Error");
}
I call it like this:
Real Time Update
As you can see, I have target="_blank", however, instead of displaying the image in a new tab, it downloads it to my documents folder. How can I get it to display in a tab?
You need a ImageController to render that.
once you have a controller you can render as follows:
public class ImageController{
public ActionResult ShowImage(string path)
{
return File(path);
}
}
in your views:
<img src="#Url.Action("Render","Image", new {id =1 // or path })" />
this answer was taken from https://stackoverflow.com/a/16142574/5586581

Download file from link inside my webpage

I have Webpage with table of objects.
One of my object properties is the file path, this file is locate in the same network. What i want to do is wrap this file path under link (for example Download) and after the user will click on this link the file will download into the user machine.
so inside my table:
#foreach (var item in Model)
{
<tr>
<th width ="150"><p><b>Download</b></p></th>
<td width="1000">#item.fileName</td>
<td width="50">#item.fileSize</td>
<td bgcolor="#cccccc">#item.date<td>
</tr>
}
</table>
I created this download link:
<th width ="150"><p><b>Download</b></p></th>
I want this download link to wrap my file path and click on thie link will lean to my controller:
public FileResult Download(string file)
{
byte[] fileBytes = System.IO.File.ReadAllBytes(file);
}
What i need to add to my code in order to acheive that ?
Return FileContentResult from your action.
public FileResult Download(string file)
{
byte[] fileBytes = System.IO.File.ReadAllBytes(file);
var response = new FileContentResult(fileBytes, "application/octet-stream");
response.FileDownloadName = "loremIpsum.pdf";
return response;
}
And the download link,
Download
This link will make a get request to your Download action with parameter fileName.
EDIT: for not found files you can,
public ActionResult Download(string file)
{
if (!System.IO.File.Exists(file))
{
return HttpNotFound();
}
var fileBytes = System.IO.File.ReadAllBytes(file);
var response = new FileContentResult(fileBytes, "application/octet-stream")
{
FileDownloadName = "loremIpsum.pdf"
};
return response;
}
In the view, write:
Download
In the controller, write:
public FileResult DownloadFile(string file)
{
string filename = string.Empty;
Stream stream = ReturnFileStream(file, out filename); //here a backend method returns Stream
return File(stream, "application/force-download", filename);
}
This example works fine for me:
public ActionResult DownloadFile(string file="")
{
file = HostingEnvironment.MapPath("~"+file);
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
var fileName = Path.GetFileName(file);
return File(file, contentType,fileName);
}
View:
< script >
function SaveImg()
{
var fileName = "/upload/orders/19_1_0.png";
window.location = "/basket/DownloadFile/?file=" + fileName;
}
< /script >
<img class="modal-content" id="modalImage" src="/upload/orders/19_1_0.png" onClick="SaveImg()">

How do I get MVC to return a Context type

I have the following code I wrote in Asp.NET and I am trying to convert it to MVC, but not sure how I do this within an Action
HttpContext context;
context.Response.ContentType = "application/pdf";
context.Response.AppendHeader("Content-Disposition", String.Format("attachment;filename={0}", filename));
context.Response.WriteFile(filename);
context.Response.Flush();
context.Response.SuppressContent = true;
public ActionResult Download()
{
var cd = new ContentDisposition
{
Inline = false,
FileName = filename
};
Response.SuppressContent = true;
Response.AppendHeader("Content-Disposition", cd.ToString());
return this.File(filename, MediaTypeNames.Application.Pdf);
}
UPDATE:
So you have a server side script (PDF.axd) which generates the PDF file. You don't have the pdf file stored on your file system. In this case you will need to first fetch the pdf and then stream it to the client:
public ActionResult Download()
{
byte[] pdfBuffer = null;
using (var client = new WebClient())
{
var url = string.Format("PDF.axd?file={0}.pdf", voucherDetail.Guid);
pdfBuffer = client.DownloadData(url);
}
var cd = new ContentDisposition
{
Inline = false,
FileName = "file.pdf"
};
Response.SuppressContent = true;
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(pdfBuffer, MediaTypeNames.Application.Pdf);
}
The usefulness of this controller action is doubtful as you already have a script that does the job.
You meant 'Content' and not 'Context' type, yes?
Maybe this SO post will help:
ASP.NET MVC and text/xml content type

Resources