I am using .net web form application in which i am downloading an excel file on button click (using ajax) for that I have created class
public class ImunizattionHelper
{
public void DownloadFile(String FileTitle,String FilePath)
{
HttpContext.Current.Response.ContentType = "APPLICATION/OCTET-STREAM";
String Header = "Attachment; Filename=" + FileTitle;
HttpContext.Current.Response.AppendHeader("Content-Disposition", Header);
System.IO.FileInfo Dfile = new System.IO.FileInfo(FilePath);
HttpContext.Current.Response.WriteFile(Dfile.FullName);
HttpContext.Current.Response.End();
}
}
I am calling this WebMethod on button click
[WebMethod]
public static void ExportChildernsToExcel(string districtID, string districtName)
{
ImunizattionHelper helper = new ImunizattionHelper();
helper.DownloadFile(districtName + "_Childrens.xlsx", HttpContext.Current.Server.MapPath("~/ExcelBackup/FileToDownload/DistrictwiseChildrens.xlsx").ToString());
}
AJAX
$("#btn_ExportChildernData").click(function () {
$.ajax({
url: 'ExportChildrenToExcel.aspx/ExportChildernsToExcel',
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: "{ districtID: '" + $("#MainContent_ddlDistrictName option:selected").val() + "', districtName: '" + $("#MainContent_ddlDistrictName option:selected").text() + "' }",
success: function (msg) {
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("responseText=" + XMLHttpRequest.responseText + "\n textStatus=" + textStatus + "\n errorThrown=" + errorThrown);
}
});
})
but this creates an error on this code
HttpContext.Current.Response.End();
and file download doesn't work. and generate an error.
Click to See Error
but if i use aspx:button and use this code on button click event (I mean without ajax)
<asp:Button ID="ExportChildernData" runat="server" Text="Export Childern Data To Excel" OnClick="ExportChildernData_Click" />
protected void ExportChildernData_Click(object sender, EventArgs e)
{
ImunizattionHelper helper = new ImunizattionHelper();
helper.DownloadFile(ddlDistrictName.SelectedItem.Text+"_Childrens.xlsx", HttpContext.Current.Server.MapPath("~/ExcelBackup/FileToDownload/DistrictwiseChildrens.xlsx").ToString());
}
it works fine
my question is why the file download does not work for ajax ? what is the correct way to download excel file from the specific path in web form application ?
How I do it is I save the file in the Cache
Dim stream As New System.IO.MemoryStream()
Using document As SpreadsheetDocument = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook, True)
WriteExcelFile(ds, document)
End Using
stream.Flush()
stream.Position = 0
If (stream.Length > 0) Then
HttpRuntime.Cache.Remove("ExcelViewerFilename")
HttpRuntime.Cache.Add("ExcelViewerFilename", filename, Nothing, DateTime.Now.AddHours(1), Nothing, CacheItemPriority.Normal, Nothing)
HttpRuntime.Cache.Remove("ExcelViewerContent")
HttpRuntime.Cache.Add("ExcelViewerContent", stream, Nothing, DateTime.Now.AddHours(1), Nothing, CacheItemPriority.Normal, Nothing)
Dim url As String = "/quotes/ExcelViewer.aspx"
Response.Redirect(url, False)
HttpContext.Current.ApplicationInstance.CompleteRequest()
Else
Throw New HttpException("Error Creating File")
End If
and then send them to a new page called "ExcelViewer.aspx" and then in the PreRender I have this:
Protected Sub Page_PreRender(sender As Object, e As System.EventArgs) Handles Me.PreRender
Dim excelStream As MemoryStream
Dim excelFilename As String
excelStream = CType(Cache("ExcelViewerContent"), MemoryStream)
excelFilename = CType(Cache("ExcelViewerFilename"), String)
Response.ClearContent()
Response.Clear()
Response.Buffer = True
Response.Charset = ""
Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache)
Response.AddHeader("content-disposition", Convert.ToString("attachment; filename=") & excelFilename)
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
Response.BinaryWrite(excelStream.ToArray())
Response.Flush()
HttpContext.Current.ApplicationInstance.CompleteRequest()
End Sub
Forgive the VB code. Works fine.
Why don't you use FileContentResult ?
public static FileContentResult ExportChildernsToExcel(string districtID, string districtName)
{
string filePath = HttpContext.Current.Server.MapPath("~/ExcelBackup/FileToDownload/DistrictwiseChildrens.xlsx").ToString();
return File(filePath, "application/vnd.ms-excel", districtName + "_Childrens.xlsx");
}
Related
I am using elasticsearch to query in index of PDFs on a asp.net mvc app. When I get the result I would like the user to be able to click the returned filename to download that file. Researching how to enable this functionality has returned plenty of results but none seem to work for me. I would simply like the user to be able to click on the filename and have the file download for them. I am using the below code.
To generate the dynamic table with search results
var row = $("<tr><th>" + "Search Results" + "</th><th>" + "File Name" + "</th>");
$("#myTable").append(row);
for (var i = 0; i < response.datasend.length; i++) {
var pos = response.datasend[i].Attachment.Content.indexOf(obj.searchterm);
var row = $("<tr><td>" + response.datasend[i].Attachment.Content.slice((pos - 100), (pos + 100)) + "</td><td><a href=# id=fileName>"
+ response.datasend[i].filename + "</a></td></tr>");
$("#myTable").append(row);
}
To detect the requested filename and call the function to start the download process
var table = document.getElementById("myTable");
table.addEventListener("click", function(e) {
if (e.target && e.target.id == "fileName")
{
var apiUrl = "/AllSearch/Download";
var obj = {};
obj.searchterm = e.target.innerHTML;
var params = e.target.innerHTML;
$.ajax({
contentType: 'application/json',
url: apiUrl,
dataType: "json",
data: {fileName: obj.searchterm},
success: function(data) {
alert("success");
},
error: function (xhr, err) {
alert("ready state: " + xhr.readyStat + " " + xhr.status);
}
});
}
});
To start download the file
public ActionResult Download(string fileName)
{
string filename = fileName;
string filePath = #"C:;at\to\file\Documents\" + fileName;
byte[] filedata = System.IO.File.ReadAllBytes(filePath);
string contentType = MimeMapping.GetMimeMapping(filePath);
var cd = new System.Net.Mime.ContentDisposition
{
FileName = filename,
Inline = true,
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(filedata, contentType);
}
The Download function is from Returning a file to View/Download in ASP.NET MVC but it returns an error when I run it. Not sure what I am missing here. Any help is appreciated
After calling API to get data, I need to generate the PDF file to PRINT using the default available.
Currently, Im able to get the data but then PDF not generated or downloaded.
AJAX codes to call controller to process request.
$(document).on('click', '#RePrint', function (event) {
var checkedVals = $('.ExportOrder:checkbox:checked').map(function () {
var orderId = this.value;
var status = document.getElementById(orderId).innerText;
if (status != "Received")
{
return this.value;
}
}).get();
if (checkedVals.length > 0) {
$.ajax({
url: '/Orders/RePrintLabel',
type: 'POST',
data: { ExportOrder: checkedVals },
dataType: "json",
async: true
});
}
});
Controller:
public ActionResult RePrintLabel(string[] ExportOrder)
{
var orders = ExtractOrders(ExportOrder, "Reprint");
if (orders.Count() > 0)
{
foreach (var item in orders)
{
var label = _orderMgr.RePrintLabel(item);
//Generate PDF For Label
if (label != null)
{
if (label.success)
{
byte[] byteContent = label.labels[0];
MemoryStream pdf = new MemoryStream(byteContent);
Response.Clear();
Response.ContentType = "application/pdf";
string pdfName = label.order_number;
Response.AddHeader("Content-Disposition", "attachment; filename=" + pdfName + ".pdf");
Response.ContentType = "application/pdf";
Response.Buffer = true;
Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
Response.BinaryWrite(byteContent);
Response.End();
Response.Close();
}
}
}
}
return RedirectToAction("Export");
}
The data is successfully returned and able to execute until this code Response.Close(); pdf was not downloaded or displayed to print.
Is there a way that I could automatically print the PDF file right after it is generated or the data is returned successfully using a default printer?
Thank you in advance for your help. Really appreciated.
I am using a webgrid and I have put a download button inside it to download a file from the grid.
But it throws an error: localhost sent an invalid response.
ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION
[HttpGet]
public ActionResult DownloadStories()
{
string filename = "saddam.png";
string filepath = Server.MapPath("~/UploadedFiles/") + filename; //AppDomain.CurrentDomain.BaseDirectory + "/UploadedFiles/" + filename;
byte[] filedata = System.IO.File.ReadAllBytes(filepath);
string contentType = MimeMapping.GetMimeMapping(filepath);
var cd = new System.Net.Mime.ContentDisposition
{
FileName = filename,
Inline = true,
};
// Response.AppendHeader("Content-Disposition", cd.ToString());
Response.AddHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");
return File(filedata, contentType, cd.FileName);
}
View:
WebGrid wgImages = new WebGrid(listData, rowsPerPage: 20);
#wgImages.GetHtml(tableStyle: "table table-condensed table-bordered table-striped table-responsive",
columns: wgImages.Columns(
wgImages.Column
(columnName: "Image", header:"Image"),
wgImages.Column
(columnName:"Story", header: "Story"),
wgImages.Column
(columnName:"Image", header:"Download", format: (testItem)=> Html.ActionLink("Download", "DownloadStories", "Stories")
))
);
}
I have tried the code which I have commented now and that doesn't work too.
Why not use simple HTML & JAVASCRIPT TO download the file by making an ajax call
1. Call this funcation by ajax post
[HttpPost]
public JsonResult DownloadStories(String someParamsIfany)
{
//do your thing
return Json(file,JsonRequestBehavior.AllowGet);
}
2. create an Img file with the data & download it on Html Side
$.ajax({
type: "POST",
url: '/Home/DownloadStories',
data: {someParamsIfany :someParamsIfany},
success: function (result) {
DownLoadTheFile(result);
}
});
3 now function DownLoadTheFile
function DownLoadTheFile(file){
var a = document.createElement('a');
a.href = file.filepath ;
a.download = file.filename;
a.click();
}
I'm trying to download an excel file (generated on the fly) on a button click. The functionality works fine when the code is placed server side (Reports.aspx.cs) and there is a postback on the button click.
But, now, the front-end technology is Angular. So no postbacks. Tried to use the same download code in a handler and the download doesnt occur. No Save prompts, no errors. The breakpoint hits the handler.cs though.
Reports.aspx:
<button type="button" data-ng-click="DownloadExcelReport()">Download Report</button>
ReportsCtrl.js --controller
$scope.DownloadExcelReport = function () {
ReportsFactory.DownloadReport($scope.ReportId,$scope.SetId);
}
ReportsFactory.js --service
factory.DownloadReport = function (reportId, setId) {
return $http({
url: "http://localhost:62102/download.ashx?reportId=" + reportId + "&setId=" + setId,
method: "GET"
}).success(function (data, status) {
}).error(function (data, status) {
});
}
download.ashx.cs --handler
public void ProcessRequest(HttpContext context)
{
int reportId = Convert.ToInt32(context.Request.QueryString["reportId"]);
int setId = Convert.ToInt32(context.Request.QueryString["setId"]);
switch (reportId)
{
case 1:
DataTable dt = GetData(reportId, setId);
if (dt != null)
{
string FileName = "Responses";
ExportExcel obj = new ExportExcel();
obj.showGridLines = true;
obj.headerStyle = new Style(Color.SlateGray, Color.White, Color.SlateGray, ExcelBorderStyle.Thin);
MemoryStream ms = obj.GenerateDocument(dt);
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + FileName + ".xlsx" + "\"");
HttpContext.Current.Response.BinaryWrite(ms.ToArray());
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
}
break;
}
}
EDIT:
I have later been taught that, when using Javascript to download, the approach is different.You create a form and then submit the form with parameters. I have added the working solution.
This might help someone.
ReportsFactory.js --service
factory.DownloadReport = function (reportId, setId) {
var form = document.createElement("form");
form.action = "http://localhost:62102/download.asmx/DownloadReport";
form.method = "POST";
form.target = "_self";
var input = document.createElement("input");
input.type = "text";
input.name = "params";
input.value = reportId + "," + setId;
form.appendChild(input);
form.style.display = 'none';
document.body.appendChild(form);
form.submit();
};
Using a asmx file now instead of handler.
download.asmx.cs
[WebMethod]
public void DownloadReport()
{
string[] Params = Convert.ToString(HttpContext.Current.Request.Form["params"]).Split(',');
string FileName = "Reports_";
int reportId = Convert.ToInt32(Params[0]);
int setId = Convert.ToInt32(Params[1]);
DataTable dt = GetData(reportId,setId);
ExportExcel obj = new ExportExcel();
MemoryStream ms = obj.GenerateDocument(dt);
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + FileName + ".xlsx" + "\"");
HttpContext.Current.Response.BinaryWrite(ms.ToArray());
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
}
I'm trying to upload a file using AJAX the problem is I'm a rookie in .net and don't know if I did this right or not so I appreciate any help or suggestions.
here is my html code:
<asp:FileUpload ID="FileUpload1" onChange="Show()" runat="server" />
My method should be called when users selects their file
this is the script I found in MSDN:
<script type="text/javascript">
function Show() {
var file = document.getElementById("FileUpload1");
alert("test")
$.ajax({
type: "POST",
url: "SendSms.aspx/StaticUpdate",
data: '{name:"test" }',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
failure: function (response) {
alert("test1");
}
});
}
function OnSuccess(response) {
alert("test2");
}
</script>
and here is my ASP method:
[System.Web.Services.WebMethod]
public static void StaticUpdate()
{
SendSms upload = new SendSms();
upload.Upload();
}
public void Upload()
{
string FileName = System.DateTime.Now.ToString("ddmmyyhhmmsss") + FileUpload1.FileName;
if (IsPostBack)
{
Boolean fileOK = false;
String path = Server.MapPath("~/Upload/");
if (FileUpload1.HasFile)
{
String fileExtension =
System.IO.Path.GetExtension(FileName).ToLower();
String[] allowedExtensions = { ".txt" };
for (int i = 0; i < allowedExtensions.Length; i++)
{
if (fileExtension == allowedExtensions[i])
{
fileOK = true;
}
}
}
if (fileOK)
{
try
{
FileUpload1.PostedFile.SaveAs(path
+ FileName);
System.IO.StreamReader myFile =
new System.IO.StreamReader("C:\\inetpub\\wwwroot\\Viber_Bulk_UI\\Upload\\" + FileName + "");
TextBox2.Text = myFile.ReadToEnd();
myFile.Close();
string Path = "C:\\inetpub\\wwwroot\\Viber_Bulk_UI\\Upload\\" + FileName + "";
System.IO.File.Delete(Path);
}
catch (Exception ex)
{
Label1.Text = "File could not be uploaded.";
}
}
else
{
Label1.Text = "Cannot accept files of this type.";
}
}
}
The error I get is this:
NullReferenceException was unhandled by user code.
Object reference not set to an instance of an object.
Thanks in advance
string filename = System.IO.Path.GetFileName(FileUpload1.FileName);
string ext = System.IO.Path.GetExtension(FileUpload1.FileName);
if (fileExtension == ".txt"){
using (System.IO.FileStream fs = new System.IO.FileStream(Server.MapPath(("C:\\inetpub\\wwwroot\\Viber_Bulk_UI\\Upload\\" + FileName), System.IO.FileMode.Append, System.IO.FileAccess.Write, System.IO.FileShare.Read, 8, System.IO.FileOptions.None))
{
byte[] data = System.Text.Encoding.ASCII.GetBytes(FileName);
fs.Write(data, 0, data.Length);
fs.Flush();
fs.Close();
}
}