asp.net download controller client from server mvc - asp.net-mvc

When I use #using (Ajax.BeginForm("Generate", "Report")) and press submit button, then the byte file is opened in end of my page
When I use Export
Export2
then the file is downloading and saving in default folder DOWNLOADS. So what is the difference between submit and a href???
public FileContentResult Generate()
{
byte[] resultee2 = new byte[12];
return new FileContentResult(resultee2, "text/plain") { FileDownloadName = "myfile.txt" };
}
And how can I create downloading file to folder after submitting form?
I have a form with fields, then I press submit button and values from fields are being send to server, server is generating byte array and then server is responding that byte array then controller has this byte array and then I want to convert this byte array to text and send to client as Download File.

Form file downloads over AJAX do not always function like opening a file from a hyperlink click or after a standard form post action. What I've done in the past is define an action:
public ActionResult Download(long id)
{
//get record info
return File(fileStream, "application/pdf");
}
I was working with PDFS in this example (note the browser by default, would open in a new tab and not prompt to download directly). And access this action via javascript:
window.open("Download?id=" + id, "_blank");
This will call the download option and return the contents. Note that this requires using some persistence mechanism, like storing the file on disk or in the database, or recreating the file from data in the database.
You also have more control if you use jQuery's $.ajax method because you have more control over the request and response, and could possibly return file data back through the AJAX call response...

Related

redirect and download pdf on click of radio button

Need a suggestion from people more intelligent than me. I have a modal which has 2 things, essentially, 3 radio buttons (Email, PDF, None)and a Yes and NO submit button.
On press of radio button I flag hidden variables appropriately to know if the user pressed email or pdf in my controller. Than user presses Yes for saving (happy path), and it will call a controller.
This controller will save the changes and redirect to a different page. Now I wanna add to this controller and make it download a pdf. I am doing this by calling my DownloadPDF action.
public ActionResult Main(string id)
//code for doing all the save and other stuff
{
if (viewModel.Email)
{
SendTestingEmail(viewModel.ConsumerEncryptedID);
}
else if(viewModel.PDF)
{
DownloadWelcomePDF()
}
return RedirectToAction("ConsumerIndex", "Consumer")
}
public ActionResult DownloadWelcomePDF(string id)
{
var htmlWelcomeEmail = db.getHtmlBody(id.DecryptID());
var converter = new ConvertToPDF();
var file = converter.ConvertHTMLStringToPDF(htmlWelcomeEmail.EmailBody);
var fileStreamResult = new FileStreamResult(file, "application/pdf") { FileDownloadName = string.Format("Welcome{0}{1}_{2}.pdf", htmlWelcomeEmail.ConsumerFirstName, htmlWelcomeEmail.ConsumerLastName, DateTime.Now.ToString("yyyyMMdd")) };
return fileStreamResult;
}
Now since this will also return pdf content I cannot do both these 2 things (redirecting to a different page and downloading ) at the same time.
Is there any suggestion, I have been searching internet for a long time.
It is essentially download and redirect but download needs to happen only on certain condition (press of radio) and the page should always redirect nonetheless.
You can break this into two steps.
First on submit you do a check in javascript to see if the user wants to download the PDF. If he wants, then call the download action and then call the main method from JS.
Or you can render the customerIndex page first and pass a flag (something like downloadPDFForId). Based on this flag in the JS in CustomerIndex you can download the file.
The first approach would be a cleaner one.

How to show a pdf file in the browser tab from an action method

I'm trying to do pdf viewer functionality in mvc application. When user click the "read the pdf" link it should open a new tab/window and user should be able view the pdf file. So I checked the examples but I couldn't find. Could you suggest me any article or example ?
Show an anchor tag in your first view and pass an id (to identify what PDF to show)
#Html.ActionLink("read the pdf","view","doc",new { #id=123},null)
Now in the doc controller, have an action method which have a parameter called id and return the pdf there using the File method.
public ActionResult View(int id)
{
byte[] byteArrayOfFile=GetFieInByteArrayFormatFromId(id);
return File(byteArrayOfFile,"application/pdf");
}
Assuming GetFileInByteArrayFormatFromId is the method which returns the byte array format of the PDF file.
You can also return the PDF if you know the full path to the PDF file physically stored, using this overload.
public ActionResult Show()
{
string path="FullPAthTosomePDFfile.pdf";
return File(path, "application/pdf","someFriendlyName.pdf");
}
Show the PDF in a browser without downloading it
Based on the browser setting of the end user, the above solution will either ask user whether he/she wishes to download or open the file or simply download/open the file. If you prefer to show the file content directly in the browser without it gets downloaded to the user's computer, you may send a filestream to the browser.
public ActionResult Show(int id)
{
// to do : Using the id passed in,build the path to your pdf file
var pathToTheFile=Server.MapPath("~/Content/Downloads/sampleFile.pdf");
var fileStream = new FileStream(pathToTheFile,
FileMode.Open,
FileAccess.Read
);
return new FileStreamResult(fileStream, "application/pdf");
}
The above code expects you to have a pdf file named sampleFile.pdf in ~/Content/Downloads/ location. If you store the file(s) with a different name/naming convention, you may update the code to build the unique file name/path from the Id passed in.
If you want to display the PDF Content in browser, you can use iTextShare dll.
Refer the link http://www.codeproject.com/Tips/387327/Convert-PDF-file-content-into-string-using-Csharp.
Reading PDF content with itextsharp dll in VB.NET or C#

Multi Post for Action with return File in ASP.NET MVC

Assume this code in One of my Actions
[HttpPost]
public ActionResult Generate (Params){
....
InsertOneRawToDB();
return RedirectToAction("Index", new { info = info });
}
So every thing is OK yet but when I change return to:
InsertOneRawToDB();
byte[] myfile = GenerateAZipFile();
return File( myfile , "application/zip" , "MyFileName");
In this case I see a weird behavior: before return, One raw inserted to DB, and after return another raw inserted, it seems the InsertOneRawToDB called again.
Does any one know about this? what happening here?
PS: I use Visual Studio 2012 RTM + ASP.NET MVC4
PS: OK I Use IDM (Internet Download Manager) to download zip file and that cause MultiPost on this Action So How can I handle this?
Based on your conclusion that the problem is related to using a download manager... That's what download mangers do. They create multiple connections to the file.
One thing you could do is store a session variable that says "Already started downloading", and then only insert the record the first time.
however if the user legitimately downloaded the file multiple times then you would only get one record.
Another option would be to examine the Http headers and look for the "Range" header, which is what is used to download a file in multiple pieces (or resume a file). You would then have to take the Range parameters and only return the portion of the file requested.
Here's an example of how to do a Ranged download: http://tpeczek.com/2011/10/range-requests-in-aspnet-mvc.html
I'm actually quite surprised that this hasn't come up before... I guess most people don't do database actions in a download action or notice it.
You can redirect to new action and in this new action return file.
[HttpPost]
public ActionResult Generate (Params){
....
InsertOneRawToDB();
return RedirectToAction("GetFile"};
}
[HttpGet]
public ActionResult GetFile
{
byte[] myfile = GenerateAZipFile();
return File(myfile, "application/zip", "filename.ext");
}

XSSFWorkbook#write() results in empty response

I'm trying to get my JSF to export a spreadsheet for download. I'm using Apache's POI library for the Excel document writing. I get the following error in an alert box when the code runs:
emptyResponse: An empty response was received from the server.
The method generating the spreadsheet and exporting to the OutputStream is below (I have renamed classes, methods etc for simplicity sake).
private void generateSpreadsheet(Object object) throws Exception {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse)context.getExternalContext().getResponse();
String fileName = object.getProperty() + ".xlsx";
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName +"\"");
OutputStream os = response.getOutputStream();
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet("Sheet 1");
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("test");
wb.write(os);
os.flush();
os.close();
FacesContext.getCurrentInstance().responseComplete();
}
Any advice much appreciated, thanks.
If it makes a difference, I'm using AJAX (<f:ajax> tag) on the form submit that calls this method.
It makes definitely difference. You can not download files by Ajax. Ajax is executed by JavaScript code. But JavaScript has no facilities to force a Save As dialogue or to execute the platform default application associated with the file's mime type (thankfully; that would have been a major security/intrusion problem). Further, the JSF Ajax API expects a XML response in a specified structure conform the JSF specs. When you send a complete Excel file instead, the whole Ajax response would be ignored as ununderstandable garbage by the JSF Ajax API.
You need to send a normal synchronous request. Remove the <f:ajax> tag from the command link/button. The current page will remain the same anyway if the download is sent as an attachment.

Downloading a file onto client in ASP.NET MVC application using JQuery

I have a ASP.NET MVC controller with a method which needs to serve up a file to the client(browser). The controller action is invoked with a JQuery $.ajax call. The user needs to be prompted to download the file once the controller action has finished.
I used Response.Transmitfile/Response.WriteFile in the controller method but both have not prompted me to download the file in IE browser even though the file has been created and I am using the right file path as well.
When i invoke the same method directly by typing the controller URL in the browser I am prompted immediately to download the file created.
Could anyone let me know if there is something missing in this flow ?
I suspect it is the way I am calling the controller action in JQuery. How do i use the response of the JQuery Ajax call to ensure the client is prompted to download the file ?
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreatePresentation(string id)
{
//do something here , create the file and place in a location on the server itself
string filename = Path.GetFileName(filePath);
Response.ContentType = "APPLICATION/OCTET-STREAM";
System.String disHeader = "Attachment; Filename=\"" + filename +
"\"";
Response.AppendHeader("Content-Disposition", disHeader);
FileInfo fileToDownload = new FileInfo(filePath);
Response.WriteFile(fileToDownload.FullName);
}
On the Javascript side, this is how i invoke the controller action
function CreatePresentation()
{
// something here
$.ajax({
type: "POST",
url: "http://localhost:4844/ActionBar/CreatePresentation",
data:data
});
} // end of function
when you use $.ajax, or for that matter any other AJAX mechanism, you're going around the normal browser file-transfer pipeline. It's the main pipeline that trigger's the browser's Save This File dialog, not the AJAX one.
To achieve what you want, you'll want to use a synchronous location change rather than an asynchronous one: rather than using $.ajax, just set document.location:
function CreatePresentation()
{
//snip code that creates a map called "data"
var paramSnippets = [];
for (item in data)
{
paramSnippets.push(item + "="+data[item]);
}
document.location = "http://localhost:4844/ActionBar/CreatePresentation" + "?" + paramSnippets.join("&");
}
edited in response to comments: included example

Resources