Can't download base64 encoded files in IE - asp.net

I've got the following Ajax call:
$.ajax({
type: 'POST',
url: 'AJAX.aspx/DownloadFile',
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data)
{
window.location.href = 'data:txt/octet-stream;base64, ' + data.d;
},
error: function (x, e)
{
alert("The call to the server side failed. " + x.responseText);
}
});
And here's my server side code:
[WebMethod]
public static string DownloadFile(){
HttpResponse response = HttpContext.Current.Response;
response.AppendHeader("Content-Disposition", "attachment;filename=b.txt");
FileStream fs = new FileStream("C:/b.txt", FileMode.OpenOrCreate);
byte[] data=new byte[fs.Length];
fs.Read(data, 0, (int)fs.Length);
fs.Close();
return Convert.ToBase64String(data);
}
I've got two problems here:
In Opera,Firefox and Chrome I can download the file composed of the base64 binary data sent from the server. The only problem with them is that the file name is the browser default.In Opera it's "default", in Chrome "download" and in Firefox something like this:"lpyQswKF.part". How can I assign the name manually?
In IE I get the following error:"The webpage cannot be displayed.Some content or files on this webpage require a program that you don't have installed."

You can assign file name like this:
var a = document.createElement("a");
a.download = "file name";
a.href = 'data:txt/octet-stream;base64,' + data.d;
document.body.appendChild(a);
a.click();
I'm still searching how to make it working in IE

Related

Asp.net webForms problem : Generate an empty pdf on production Server

In my webForm project as follow :
I have a button which user click on it
call a web method (via jquery request) to extract some binary data from sql server as pdf
Then give a user to download/view the pdf via browser.
This works for my development machine. However, this fails on production server and give to user an empty pdf!
Where is my problem & how to solve it?
Here is jquery request to my web method :
function OpenAttachment(jsonData){
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "MedicalHistory.aspx/OpenAttachment",
data: JSON.stringify({ objData: jsonData }),
dataType: "json",
success: function (response) {
gdv.PerformCallback('downloadfile|' + response.d);
},
error: function (request, status, error) {
alert('error : ' + error);
}
});
}
Here is my web method :
[WebMethod]
public static string OpenAttachment(object objData)
{
string strResult = string.Empty;
if (objData == null)
return strResult;
DataTable dtResult = Newtonsoft.Json.JsonConvert.DeserializeObject<DataTable>(objData.ToString());
string strDocContent = dtResult.Rows[0]["DocContent"].ToString();
string strFileName = dtResult.Rows[0]["FileName"].ToString();
byte[] pdfByteArray = Encoding.Default.GetBytes(strDocContent);
HttpContext.Current.Session["_binDownloadData"] = pdfByteArray;
strResult = strFileName;
return strResult;
}
And here is download code in my download page :
object objDownloadData = Session["_binDownloadData"];
if (objDownloadData != null)
{
byte[] pdfByteArray = (byte[])objDownloadData;
string strContentType = string.Empty;
if (strFileType == "pdf")
{
strContentType = "application/pdf";
}
#region Downloading file
HttpContext.Current.Response.Clear();
MemoryStream ms = new MemoryStream(pdfByteArray);
HttpContext.Current.Response.ContentType = strContentType;
HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment;filename={0}", strFileName));
HttpContext.Current.Response.Buffer = true;
ms.WriteTo(HttpContext.Current.Response.OutputStream);
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.SuppressContent = true;
HttpContext.Current.ApplicationInstance.CompleteRequest();
#endregion
Session["_binDownloadData"] = null;
}
Thanks in advance.
Try with changing contentType and dataType.
$.ajax - dataType
function OpenAttachment(jsonData){
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "MedicalHistory.aspx/OpenAttachment",
data: JSON.stringify({ objData: jsonData }),
dataType: "application/pdf",
success: function (response) {
gdv.PerformCallback('downloadfile|' + response.d);
},
error: function (request, status, error) {
alert('error : ' + error);
}
});
}

How to pass an array to asmx web service via JSON?

I want to pass array value to my web service file. But it throws the following error
setDeleteFiles
Test
The test form is only available for methods with primitive types as parameters.
Here is my jquery code
$('#btnDeleteFiles').click(function () {
var filesPaths = [];
i = 0;
$("input:checkbox[name=filed-checkedbox]:checked").each(function () {
filesPaths[i] = $(this).val();
i++;
});
//alert("filesPaths = " + filesPaths)
var location = $('#ddlLocation option:selected').text();
alert("Location = "+location)
$.ajax({
method: 'post',
url: "GetAllFolderDetails.asmx/setDeleteFiles",
data: {
location: location,
fileNames: filesPaths
},
dataType: "json",
success: function (data) {
window.location.reload(true);
//alert("Success");
},
error: function (result) {
alert("Error");
}
});
});
GetAllFolderDetails.asmx code
[WebMethod]
public void setDeleteFiles(string location, string[] fileNames)
{
var locationID = 0;
var domain = "domain";
var username = "xxx"; //username
var Password = "***"; //password
Debug.WriteLine("Location = "+location);
Debug.WriteLine("fileNames = " + fileNames);
using (new ImpersonateUser(username , domain, Password))
{
Debug.WriteLine("Files names = "+ fileNames);
foreach (string file in fileNames)
{
FileInfo files = new FileInfo(file);
files.Delete();
}
JavaScriptSerializer js = new JavaScriptSerializer();
Context.Response.Write(js.Serialize("Files are successfully Deleted"));
}
}
Note
If I pass a string as a parameter without an array, it is working fine
Use the following
data: JSON.stringify({ location: location, fileNames: filesPaths }),
contentType: "application/json; charset=utf-8",
dataType: "json",
and change the input parameter datatype as List<string> instead of string[]
Just remove
dataType: "json",
from your ajax call.
and also check in your asmx file that it is decorated with
[System.Web.Script.Services.ScriptService]
try this.

uploading image using HTML canvas

i am not able to pass parameter "image" as query string in below code.
i am trying to convert convas into image.
Then toDataURL() passed as a parameter using ajax to save the image. but there is an issue while passing toDataURL() it shows error 500.
var canvas = document.querySelector("canvas");
var ctx = canvas.getContext('2d');
html2canvas(document.querySelector("#jhdj"), { canvas: canvas }).then(function (canvas) {
// console.log('Drew on the existing canvas');
});
var image = document.getElementById("dvNCVS").toDataURL("image/png");
image = image.replace('data:image/png;base64,', '');
$.ajax({
type: 'POST',
url: '/CodePages/imUpp.aspx/UploadPic',
data: '{ "imageData" : "' + image.toString() + '" }',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (msg) {
alert("Done, Picture Uploaded.");
}
});

How to handle FormData AJAX post (file with additional params) with asp.net WebMethod

Having trouble handling a jQuery AJAX post of FormData to an ASP.net 4 Web service WebMethod.
<input id="ipt_file" type="file" />
<a href='#' onclick="UploadFile();" data-role='button'>Upload</a>
var UploadFile = function () {
var file_object = $('#ipt_file')[0].files[0];
var form_data = new FormData();
form_data.append('job_id', '123456');
form_data.append('job_name', 'xyx');
form_data.append('job_file', file_object);
var xhr_upload = $.ajax({
type: "POST",
headers: { "Cache-Control":"no-cache", "Content-Type":"multipart/form-data" }, // also tried without these
url: "../MyServices.asmx/Upload",
data: form_data,
processData: false,
contentType: false,
dataType: "json",
success: function (msg) {
if (typeof (msg) === "object") {
var _upload = $.parseJSON(msg.d);
alert(_upload.status + ': ' + _upload.msg);
};
}
});
};
public class FileUploadRequest
{
public string job_id { get; set; }
public string job_name { get; set; }
public HttpPostedFile job_file { get; set; }
}
[WebMethod]
public string Upload(FileUploadRequest x)
{
string str_response = string.Empty;
if (x.job_file.ContentLength > 0)
{
str_response = "{\"status\":1,\"msg\":\"" + x.job_id + ", " + x.job_name + ", " + x.job_file.FileName + "\"}";
}
else
{
str_response = "{\"status\":0,\"msg\":\"FAIL"\}";
};
return str_response;
}
Must not be handling the FormData object parameter properly; here I instantiated a custom class, but all I get back from the server is 500 errors (also tried a generic object x). Also tried handling it as HttpRequest object as I've seen on some postings, to no avail. Not concerned about IE 9 incompatibility in this case; just want to see single file upload or at least a FormData object with key/value pairs properly received by an asmx WebMethod.
I did get it to work with the following code, in case anyone wants to see it:
var upload_file = $('#ipt_file')[0].files[0];
var upload_filename = upload_file.name;
var upload_maxsize = 10485760;
var upload_projectname = "test";
var form_data = new FormData();
form_data.append('session_id', this.sessionID());
form_data.append('project_name', upload_projectname);
form_data.append('file_name', upload_filename);
form_data.append('file_size', upload_file.size);
form_data.append('file', upload_file);
if (upload_file.size < upload_maxsize) {
var xhr_upload = $.ajax({
type: "POST",
headers: { 'Cache-Control': 'no-cache' },
url: "../services/upload.ashx",
data: form_data,
processData: false,
contentType: false,
dataType: "json"
}
})
.done(function (xhr_data) {
...
})
.fail(function (jqXHR, textStatus, errorThrown) {
...
})
.always(function () {
...
});
.NET will not allow the multipart/form-data for the content-type:
JSON Hijacking and How ASP.NET AJAX 1.0 Avoids these Attacks
There is a built-in validation layer of protection that ASP.NET
enforces for both GET and POST based ASP.NET AJAX web methods, which
is that regardless of the HTTP verb being used, ASP.NET always
requires that the HTTP Content-Type header is set to the value
application/json. It this content type header is not sent, ASP.NET
AJAX will reject the request on the server.

Ajax Request 500 Internal Server Error in Internet Explorer

I am getting this 500 Internal Server Error only in IE 10 when I run my application that makes a simple Ajax request to a Page Method. I have tested it in Chrome and Firefox, it works fine in these. Please make any relevant suggestion ASAP.
I will paste the code below:
function GetProductId() {
$.ajax({
type: "POST",
url: "Default.aspx/GenerateQrCode",
data: "{'Products':" + JSON.stringify([{ ProductId: 1 }, { ProductId: 2 }]) + "}",
contentType: "application/json; charset=utf-8",
dataType: "json",
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(xhr.responseText);
alert(thrownError);
},
success: function (msg) {
var data = $.parseJSON(msg.d);
}
});
}
[WebMethod]
public static string GenerateQrCode(List<Product> Products)
{
List<string> images = new List<string>();
foreach(var product in Products)
{
string qrCodeLocation = (from pic in products
where pic.ProductId == product.ProductId
select pic.QrCode).FirstOrDefault().ToString();
images.Add(qrCodeLocation);
}
JavaScriptSerializer js = new JavaScriptSerializer();
return js.Serialize(images);
}
Is a bug of .Net framework:
IE10 is not mapped as IE browser, and ASP.NET throw back the JS code for a generic browser.
Add this meta-tag in the top of your master page and try again:
<meta http-equiv="X-UA-Compatible" content="IE=9"/>

Resources