How to download file via jQuery ajax and C# - c#

I want to download a file using jQuery Ajax web method, but it's not working.
Here is my jQuery ajax call to web method:
function GenerateExcel() {
var ResultTable = jQuery('<div/>').append(jQuery('<table/>').append($('.hDivBox').find('thead').clone()).append($('.bDiv').find('tbody').clone()));
var list = [$(ResultTable).html()];
var jsonText = JSON.stringify({ list: list });
$.ajax({
type: "POST",
url: "GenerateMatrix.aspx/GenerateExcel",
data: jsonText,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
},
failure: function (response) {
alert(response.d);
}
});
}
and this is the web method definition:
[System.Web.Services.WebMethod()]
public static string GenerateExcel(List<string> list)
{
HttpContext.Current.Response.AppendHeader("content-disposition", "attachment;filename=FileEName.xls");
HttpContext.Current.Response.Charset = "";
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
HttpContext.Current.Response.Write(list[0]);
HttpContext.Current.Response.End();
return "";
}
How to get it done?
One more thing: I want to download it on client PC, not to save it on server.

well i have done it using iframe
this is the modified ajax function call
function GenerateExcel() {
var ResultTable = jQuery('<div/>').append(jQuery('<table/>').append($('.hDivBox').find('thead').clone()).append($('.bDiv').find('tbody').clone()));
var list = [$(ResultTable).html()];
var jsonText = JSON.stringify({ list: list });
$.ajax({
type: "POST",
url: "GenerateMatrix.aspx/GenerateExcel",
data: jsonText,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
if (isNaN(response.d) == false) {
$('#iframe').attr('src', 'GenerateMatrix.aspx?ExcelReportId=' + response.d);
$('#iframe').load();
}
else {
alert(response.d);
}
},
failure: function (response) {
alert(response.d);
}
});
}
and this is the design part
<iframe id="iframe" style="display:none;"></iframe>
on Page load my code looks like this
Response.AppendHeader("content-disposition", "attachment;filename=FileEName.xls");
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "application/vnd.ms-excel";
Response.Write(tableHtml);
Response.End();

Add these in your view page-
<iframe id="iframe" style="display:none;"></iframe>
<button id="download_file">Download</button>
Server side
public string Download(string file)
{
string filePath = Server.MapPath(System.Configuration.ConfigurationManager.AppSettings["FileManagementPath"]);
string actualFilePath = System.IO.Path.Combine(filePath, file);
HttpContext.Response.ContentType = "APPLICATION/OCTET-STREAM";
string filename = Path.GetFileName(actualFilePath);
String Header = "Attachment; Filename=" + filename;
HttpContext.Response.AppendHeader("Content-Disposition", Header);
HttpContext.Response.WriteFile(actualFilePath);
HttpContext.Response.End();
return "";
}
Add this code in your JavaScript
<script>
$('#download_file').click(function(){
var path = 'e-payment_format.pdf';//name of the file
$("#iframe").attr("src", "/FileCabinet/Download?file=" + path);
});
</script>
That should work!

Assuming the C# code responds with the correct headers for Excel, you can simply redirect to the link instead of using ajax:
var list = [$(ResultTable).html()];
var url = "GenerateMatrix.aspx/GenerateExcel";
var data = {list: list};
url += '?' + decodeURIComponent($.param(data));
// if url is an excel file, the browser will handle it (should show a download dialog)
window.location = url;

Related

Link inside Link web method

Hi i am trying to navigate through anchor link. Only the first link works. For example if i click a link in a page it goes to that link, but when there is another link in page whcih i have clicked it doesnt work. And also the second has the same class 1st link Please help.
$('#frmDisplay').on('load', function () {
$('#frmDisplay a.anchorLink').on('click', function () {
var id = $(this).attr('id');
var hid = document.getElementById('<%= HiddenField1.ClientID %>');
hid.value = id;
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Amm.aspx/getlink",
data: "{'Id': '" + id + "'}",
dataType: "json",
success: function (data) {
$('#frmDisplay').contents().find('html').html(data.d);
},
error: function (response) {
alert(response.responseText);
}
});
});
});
public static string getlink(int Id)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["connString"].ConnectionString);
string link = "extlink";
BookTree obj = new BookTree();
DataSet ds = obj.getlink(Id);
SqlCommand cmd=new SqlCommand("select vcFilePath from tblBookNodes where iModuleId='" + Id + "'",conn);
conn.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
bytes = (byte[])dr["vcFilePath"];
}
string fileName = link.Replace(" ", "_") + ".htm";
// DirectoryInfo strPath = new DirectoryInfo(HttpContext.Current.Server.MapPath(#"~/Linking/"));
//string strPath = HttpContext.Current.Server.MapPath(#"/Linking/") + fileName;
//foreach (FileInfo file in strPath.GetFiles())
//{
// file.Delete();
//}
string path = Path.Combine(HttpContext.Current.Server.MapPath("~/htmlFile/"), fileName);
var doc = new HtmlDocument();
string html = Encoding.UTF8.GetString(bytes);
doc.LoadHtml(html);
StringWriter sw = new StringWriter();
var hw = new HtmlTextWriter(sw);
StreamWriter sWriter = new StreamWriter(path);
sWriter.Write(sw.ToString());
doc.Save(sWriter);
sWriter.Close();
//string fileContents = html;
//System.IO.File.WriteAllText(path, html);
return File.ReadAllText(path);
}
You have to use "on" instead of find() and event listener attach.
Please refer to this example:
$('#formDisplay a.anchroLink').on('click', function() {
// TODO: handle the click
})
This is necessary because when you add the event listener the DOM is not yet ready to handle requests for non existing content. Using "on" you can attach an event to a class or a simple DOM query.
To be more clear I post your code with modifications based on my previous suggestion:
$('#frmDisplay a.anchorLink').on('click', function () {
var id = $(this).attr('id');
var hid = document.getElementById('<%= HiddenField1.ClientID %>');
hid.value = id;
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Amm.aspx/getlink",
data: "{'Id': '" + id + "'}",
dataType: "json",
success: function (data) {
$('#frmDisplay').contents().find('html').html(data.d)
},
error: function (response) {
alert(response.responseText);
}
});
});
My last answer (I don't know you were using iFrames):
function clickHandler() {
var id = $(this).attr('id');
var hid = document.getElementById('<%= HiddenField1.ClientID %>');
hid.value = id;
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Amm.aspx/getlink",
data: "{'Id': '" + id + "'}",
dataType: "json",
success: function (data) {
$('#frmDisplay').contents().find('html').html(data.d);
// You can reload the event handler because the prev one
// has been lost after refreshing the page with the ajax call.
$('#frmDisplay').contents()
.find('a.anchorLink')
.click(clickHandler);
},
error: function (response) {
alert(response.responseText);
}
});
}
$('#frmDisplay').on('load', function () {
$('#frmDisplay')
.contents()
.find('a.anchorLink')
.on('click', clickHandler);
})

Delete image from folder using AJAX C#

I am trying to delete an image from a folder by using AJAX and C#. I have created a handler called Delete.ashx to delete the image. I also have an AJAX function to get the image path and pass the path to the handler
In AJAX I have a variable that gets the path which is stored in a textbox (just for now). I make an attempt to pass that path to my handler, however the problem is that the variable in the handler which I am trying to pass the data path to is always empty.
Here is my code:
Handler
public void ProcessRequest(HttpContext context)
{
string sFileName = context.Request["sFileName"]; //this variable is always empty
if (File.Exists(context.Server.MapPath("~/images/" + sFileName)))
{
File.Delete(context.Server.MapPath("~/images/" + sFileName));
context.Response.ContentType = "text/plain";
context.Response.Write("Image deleted Successfully!");
}
else
{
context.Response.ContentType = "text/plain";
context.Response.Write("Image Failed to Delete!");
}
}
AJAX
$(document).ready(function () {
$("#btnDelete").click(function () {
removeFile();
return false;
});
function removeFile() {
var FileName = $("#txtPath").val();
$.ajax({
url: 'Delete.ashx',
type: 'POST',
data: { 'sFileName': FileName},
contentType: false,
processData: false,
success: function (result) {
alert(result);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(xhr.responseText);
alert(thrownError);
}
});
}
});
Please advise how I can pass data from AJAX to the handler so that the variable is not empty. Thank you.
try to get context from current HttpContext:
1
public void ProcessRequest(HttpContext context)
{
var context_= System.Web.HttpContext.Current;
string sFileName = context_.Request["sFileName"];
if (File.Exists(context_.Server.MapPath("~/images/" + sFileName)))
{
File.Delete(context_.Server.MapPath("~/images/" + sFileName));
context_.Response.ContentType = "text/plain";
context_.Response.Write("Image deleted Successfully!");
}
else
{
context_.Response.ContentType = "text/plain";
context_.Response.Write("Image Failed to Delete!");
}
}
2
Or send data with querystring from ajax
modify ajax:
url: 'Delete.ashx?sFileName=blabla',
server side:
var sFileName= Request.Form["sFileName"];
With the help of Mennan I have done the following and is working:
public void ProcessRequest(HttpContext context)
{
string sFileName = context.Request["sFileName"];
if (File.Exists(context.Server.MapPath("~/images/" + sFileName)))
{
File.Delete(context.Server.MapPath("~/images/" + sFileName));
context.Response.ContentType = "text/plain";
context.Response.Write("Image deleted Successfully!");
}
else
{
context.Response.ContentType = "text/plain";
context.Response.Write("Image Failed to Delete!");
}
}
function removeFile() {
var FileName = $("#txtPath").val();
$.ajax({
url: 'Delete.ashx?sFileName=' + FileName,
type: 'POST',
data: { 'sFileName': FileName},
contentType: false,
processData: false,
success: function (result) {
alert(result);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(xhr.responseText);
alert(thrownError);
}
});
}

Displaying PDF from byte[] in MVC 4

I'm using Grid.MVC to display data from an entity model. On row click I am getting the value of a cell and passing it to my controller with a json/ajax function.
In my controller the int "ticketnumber" is passing just fine. The thing that I am not understanding is when I hard code the int, it is working (if I directly browse to http://localhost:58779/ticket/PDFVIEW).
The controller seems to be running through just fine, but it is not displaying the PDF..it just takes me back to my grid in my view with the ajax script. Thanks for the help.
Edit - Code:
<script>
$(function () {
pageGrids.TicketGrid.onRowSelect(function (e) {
var ticketnumber = e.row.UnsettledID;
ticketnumber = JSON.stringify({ 'ticketnumber': ticketnumber });
$.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: 'POST',
url: '/ticket/PDFVIEW',
data: ticketnumber,
});
});
});
</script>
controller:
[ActionName("PDFVIEW")]
[HttpGet]
public ActionResult PDFVIEW(int ticketnumber)
{
var db = new ScaleTrac_VerticalEntities();
Ticket_UnsettledScaleImages tu = new Ticket_UnsettledScaleImages();
tu = db.Ticket_UnsettledScaleImages.Where(p => p.UnsettledID == ticketnumber).First();
string filename = "ScaleTick" + tu.UnsettledID + ".pdf";
{
byte[] bytes = tu.ScaleTicket;
TempData["bytes"] = bytes;
Response.Clear();
MemoryStream ms = new MemoryStream(bytes);
return new FileStreamResult(ms, "application/pdf");
}
}
You can't use AJAX to download a file in this way. Your AJAX code is getting the contents of the PDF, but your browser needs to receive it as a normal request in order to view it. You should instead render a link to the PdfView action, or use window.setLocation if you need to do it from a Javascript event handler.
Note you'll also need to change your action method to accept HttpGet.
Using what Richard said helped a lot.
My Json I changed to:
<script>
$(function pdfviewer() {
pageGrids.TicketGrid.onRowSelect(function (e) {
var ticketnumber = e.row.UnsettledID;
ticketnumber = JSON.stringify({ 'ticketnumber': ticketnumber });
$.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: 'POST',
url: '/ticket/PDFVIEW',
data: ticketnumber,
success: function (d) {
if (d.success) {
window.location = "/Ticket/DownloadFile" + "?fName=" + d.fName;
}
},
error: function () {
alert("Error");
}
});
});
});
</script>
And in my controller I did:
[ActionName("PDFVIEW")]
public ActionResult pdf(int ticketnumber)
{
var db = new ScaleTrac_VerticalEntities();
Ticket_UnsettledScaleImages tu = new Ticket_UnsettledScaleImages();
tu = db.Ticket_UnsettledScaleImages.Where(p => p.UnsettledID == ticketnumber).First();
string filename = "ScaleTick" + tu.UnsettledID + ".pdf";
{
byte[] bytes = tu.ScaleTicket;
TempData["bytes"] = bytes;
Response.Clear();
MemoryStream ms = new MemoryStream(bytes);
var fName = string.Format("File-{0}.pdf", DateTime.Now.ToString("s"));
Session[fName] = ms;
return Json(new { success = true, fName }, JsonRequestBehavior.AllowGet);
}
}
public ActionResult DownloadFile(string fName)
{
var ms = Session[fName] as MemoryStream;
if (ms == null)
return new EmptyResult();
Session[fName] = null;
return File(ms, "application/pdf", fName);
}
Thank you very much!

Using uploadify with ashx handler

Hi friends i have a form in which there are some text boxes, drop downs and as well as image . I am using knock out js to save the form details. And i am using uploadify plugin to upload my image to a local folder .I have implemented all this things but when it comes to saving the values till now i used a aspx code behind . For uploading purpose we had to choose ashx. So it will be like two server side postings going to happen!!
So i would like to save my data in ashx page rather than aspx.
But i am confused where exactly to start my upload..please some one help me with this!!!
i am saving my values in a save button event like below!!
self.AddEvent = function (args) {
// Here--> $('#file_upload').uploadify('upload');
ajax.Post("../Scripts/uploadify/UploadHandler.ashx", JSON.stringify({ objEnt: args }), false).success(function (data) {
if (data.d[0] > 0) {
// or Here--> $('#file_upload').uploadify('upload');
alert('success');
}
and my fileupload setting s are:
$('#file_upload').uploadify({
'swf': '../Scripts/uploadify/uploadify.swf',
'uploader': '../Scripts/uploadify/UploadHandler.ashx',
'method': 'post',
'formData': { 'someKey': Filename },
'buttonText': 'Browse',
'auto': false,
'folder': 'upload',
'fileTypeExts': '*.jpg;*.jpeg;*.gif;*.png',
'onSelect': function (file) {
var ext = file.name.split('.').pop();
$("#filename").val(Filename + '.' + ext);
},
'onUploadSuccess': function (file, data, response) {
if (response == true) {
$("#eventGrid").jqxGrid('updatebounddata');
}
}
});
It is not possible to call self.AddEvent in 'onUploadsuccess' in my situation...!!!
Please suggest me some best way to store my data and image at same time in ashx handler.
ashx:
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "application/json";
var data = context.Request;
var sr = new StreamReader(data.InputStream);
var stream = sr.ReadToEnd();
var javaScriptSerializer = new JavaScriptSerializer();
var asd = javaScriptSerializer.Deserialize<RootObject>(stream);
string Newname = context.Request.Form["someKey"];
BAL Bl = new BAL();
string[] args = new string[2];
//AddEvent method will add my data into database add return response "Success"//
args = AddEvent(asd.objEnt);
HttpPostedFile PostedFile = context.Request.Files["Filedata"];
string ext = Path.GetExtension(PostedFile.FileName);
string savepath = "";
string temppath = "";
temppath = System.Configuration.ConfigurationManager.AppSettings["FolderPath"];
savepath = context.Server.MapPath(temppath);
string fileName = Newname + ext;
if (!Directory.Exists(savepath))
Directory.CreateDirectory(savepath);
PostedFile.SaveAs(savepath + #"\" + fileName);
context.Response.Write(temppath + "/" + fileName);
// context.Response.Write(args);
context.Response.StatusCode = 200;
}
}
$("#<%=FileUpload1.ClientID%>").uploadify({
'uploader': 'Upload.ashx',
'swf': 'uploadify/uploadify.swf',
'script': 'Upload.ashx',
'cancelImg': 'images/cancel.png',
'folder': '../Upload',
'multi': true,
'buttonText': 'select picture',
'fileExt': '*.jpg;*.png;*.gif;*.bmp;*.jpeg',
'auto': false,
'onUploadStart': function () {
}
});
$.ajax({
type: "POST",
url: 'WebServiceAdmin.asmx/SaveData',
data: "{'p':'" + datam+ "'}",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (d) { $('#FileUpload1').uploadify('upload', '*'); },
error: function () { }
});

Export to Excel Not Working in WEB API

I am trying to export to excel a JQGrid data from WEB API controller ..Need to handle it from a controller method ..Everything is going fine but Excel is not showing ....
<input type="image" src="../images/Excel.jpg" alt="Submit" width="20" height="20"
id="btnExport" runat="server" onclick="ExportData();" />
function ExportData() {
//debugger;
var tblHTML = createGridStructureForPrint($("#table3"));
tblHTML = escape(tblHTML);
var ExportData = tblHTML;
var source = {
'ExportData': ExportData
};
var apiUrlExport = '../api/Home/ExportData?source=' + source ;
$.ajax({
type: "POST",
dataType: "json",
url: apiUrlExport,
beforeSend: function () {
$('#dvStatus').show("slow");
},
data: JSON.stringify(source),
contentType: 'application/json; charset=utf-8',
success: function (data) {
debugger;
},
error: function (ex) {
},
complete: function () {
$('#dvStatus').hide("slow");
}
});
};
[HttpPost]
public void ExportData(ExportToExcel source)
{
try
{
string data = source.ExportData;
data = HttpUtility.UrlDecode(data);
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=Data.xls");
HttpContext.Current.Response.ContentType = "application/excel";
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.Unicode;
HttpContext.Current.Response.BinaryWrite(System.Text.Encoding.Unicode.GetPreamble());
System.IO.StringWriter sw = new System.IO.StringWriter();
sw.Write(data.ToString());
System.Web.UI.HtmlTextWriter hw = new HtmlTextWriter(sw);
HttpContext.Current.Response.Write(sw.ToString());
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
}
catch (Exception ex)
{
throw ex;
}
}
Not sure where i am doing wrong ..
Rahul, you might want to look into JQGrid.ExportSettings and JQGrid.ExportToExcel. I have found it simpler than Http Response...

Categories

Resources