Using uploadify with ashx handler - c#

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 () { }
});

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);
})

How to secure file download via controller action and ajax?

I have an application where I want users to be able to upload and download their own files. I implemented the upload and download however I am concerned with XSS vulnerability of the download action. I was only able to implement the file actually downloading using GET method, but I want to secure it (usually I use POST + antiforgery token). How can I do this?
This is my controller action:
public ActionResult DownloadFile(int clientFileId)
{
var clientId = GetClientId(clientFileId);
var client = _unitOfWork.Clients.GetById(clientId);
if (client == null)
return HttpNotFound();
var file = _unitOfWork.ClientFiles.GetById(clientFileId);
if (file == null)
return HttpNotFound();
var practiceId = _unitOfWork.Users.GetPracticeIdForUser(User.Identity.GetUserId());
if (!AuthorizationHelper.CheckBelongsToPractice(_unitOfWork.Clients, typeof(Client),
practiceId, client.Id, nameof(Client.Id), nameof(Client.PracticeId)))
{
return new HttpUnauthorizedResult();
}
var fileInfo = new FileInfo(file.FilePath);
var fileName = fileInfo.Name;
if (!fileInfo.Exists)
return HttpNotFound();
var path = Path.Combine(Server.MapPath("~/ClientFiles/" + clientId + "/"), fileName);
var contentType = MimeMapping.GetMimeMapping(path);
try
{
var contentDisposition = new System.Net.Mime.ContentDisposition
{
FileName = fileName,
Inline = false,
};
Response.AppendHeader("Content-Disposition", contentDisposition.ToString());
return File(path, contentType, fileName);
}
catch (Exception ex)
{
new ExceptionlessLogger(ex).Log();
return new HttpStatusCodeResult(500);
}
}
And my ajax call
$('#client-files-table').on('click', '.js-download', function () {
var link = $(this);
$.ajax({
url: '/clients/clientfiles/downloadfile?clientFileId=' + link.attr('data-clientfile-id'),
method: 'GET',
//data: {
// __RequestVerificationToken: getToken()
//},
success: function () {
window.location = '/clients/clientfiles/downloadfile?clientFileId=' + link.attr('data-clientfile-id'),
loadPartials();
},
error: function () {
toastr.error('Unable to download.');
}
});
});
I found the answer here: https://codepen.io/chrisdpratt/pen/RKxJNo
$('#client-files-table').on('click', '.js-download', function () {
var link = $(this);
$.ajax({
url: '/clients/clientfiles/downloadfile?clientFileId=' + link.attr('data-clientfile-id'),
method: 'POST',
data: {
__RequestVerificationToken: getToken()
},
xhrFields: {
responseType: 'blob'
},
success: function (data, status, xhr) {
var a = document.createElement('a');
var url = window.URL.createObjectURL(data);
a.href = url;
var header = xhr.getResponseHeader('Content-Disposition');
var filename = getFileNameByContentDisposition(header);
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);
loadPartials();
},
error: function () {
toastr.error('Unable to download.');
}
});
});

How to get Base64 from ajax Post?

I was trying to get the base64 post in my codebehind webmethod,
but it seems like everytime I include the base64 I get an error : the server responded with a status of 500 (Internal Server Error) - it keeps on hitting the error function.
The Post works with the other strings when the base64 is not inlcuded int the data that im passing.
function event_create() {
alert("alert test : function works => onclick");
function getBase64(file) {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
console.log(reader.result);
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
}
var eventTitle = $("#eventTitle").val();
var eventDesc = $("#eventDesc").val();
var eventTimeStart = $("#eventTimeStart").val();
var eventTimeEnd = $("#eventTimeEnd").val();
var eventDateStart = $("#eventDateStart").val();
var eventDateEnd = $("#eventDateEnd").val();
var eventType = $("#eventType").val();
var eventPlace = $("#eventPlace").val();
var eventAttendee = document.getElementById("lblSelected").innerText;
var userID = sessionStorage.getItem("userID");
var imageBase64 = getBase64(document.getElementById('test').files[0]);
var data = { 'eventTitle': eventTitle, 'eventDesc': eventDesc, 'eventPlace': eventPlace, 'eventType': eventType, 'eventAttendee': eventAttendee, 'userID': userID, 'imageBase64': imageBase64};
$.ajax({
type: "POST",
async: true,
contentType: "application/json; charset=utf-8",
url: ".../../../../Operation/insert.aspx/createEvent",
data: JSON.stringify(data),
datatype: "json",
success: function (result) {
if (result.d <= 0) {
//false alert something
alert("FALSE");
}
else if (result.d > 0) {
//true
alert(result.d);
}
else {
alert("sent but no call-back");
}
console.log(result);
},
error: function (xmlhttprequest, textstatus, errorthrown) {
alert(" connection to the server failed ");
console.log("error: " + errorthrown);
}
});
}
Here's the Webmethod that will get the post
[WebMethod(EnableSession = true)]
public static string createEvent(string eventTitle, string eventDesc, string eventPlace, string eventType, string eventAttendee, string userID, string imageBase64)
{
String orgID = (String)HttpContext.Current.Session["orgID"];
string response = orgID;
string path = HttpContext.Current.Server.MapPath("~/Users/Organizer/organizerData/"); // de path
//Check if directory exist
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path); //Create directory if it doesn't exist
}
string imageName = "event1" + ".jpg";// for instance
//set the image path
string imgPath = Path.Combine(path, imageName);
byte[] imageBytes = Convert.FromBase64String(imageBase64);
File.WriteAllBytes(imgPath, imageBytes); //write the file in the directory
return imageBase64;
}

'Not found' error in upload file using jquery and handler(ashx)

UploadHandler.ashx.cs
public class UploadHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
try
{
string dirFullPath = HttpContext.Current.Server.MapPath("~/Uploader/");
string[] files;
int numFiles;
files = System.IO.Directory.GetFiles(dirFullPath);
numFiles = files.Length;
numFiles = numFiles + 1;
string str_image = "";
foreach (string s in context.Request.Files)
{
HttpPostedFile file = context.Request.Files[s];
string fileName = file.FileName;
string fileExtension = file.ContentType;
if (!string.IsNullOrEmpty(fileName))
{
fileExtension = Path.GetExtension(fileName);
str_image = "MyPHOTO_" + numFiles.ToString() + fileExtension;
string pathToSave_100 = HttpContext.Current.Server.MapPath("~/Uploader/") + str_image;
file.SaveAs(pathToSave_100);
}
}
// database record update logic here ()
context.Response.Write(str_image);
}
catch (Exception ac)
{
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
JsCode
/Image Upload code
function sendFile(file) {
var formData = new FormData();
formData.append('file', $('#f_UploadImage')[0].files[0]);
$.ajax({
url: 'UploadHandler.ashx',
type: 'POST',
data: formData,
cache: false,
processData: false,
contentType: false,
success: function(result) {
if (result != 'error') {
var my_path = "Uploader/" + result;
$("#myUploadedImg").attr("src", my_path);
}
},
error: function(err) {
alert(err.statusText);
}
});
}
function callImgUploader() {
var _URL = window.URL || window.webkitURL;
$("#f_UploadImage").on('change', function() {
var file, img;
if ((file = this.files[0])) {
img = new Image();
img.onload = function() {
sendFile(file);
};
img.onerror = function() {
alert("Not a valid file:" + file.type);
};
img.src = _URL.createObjectURL(file);
}
});
}
Note: My Aspx page is different folder and Image Folder and UploadHandler.ashx.cs is route folder its wrong?
after run ajax request every time its give Not-Found error how can its fixed.
Thanks.
You didn't mentioned which upload control you are using , i'm assuming it is a server side and you need to access it as follows
Change
$('#f_UploadImage')
to
$('#<%= f_UploadImage.ClientID %>')
As you said
My Aspx page is different folder and Image Folder and UploadHandler.ashx.cs
You have to change
url: 'UploadHandler.ashx',
to
url: '/UploadHandler.ashx',
Otherwise it will try to search UploadHandler.ashx in the same folder as of ajax page and give 404.
I think the problem is with the contentType try
contentType: 'multipart/form-data',
Thanks for all of your valuable feedback,
now my problem has been fixed,
problem in UploadHandler.ashx setting
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="UploadHandler.ashx.cs" Inherits="Customer.UploadHandler" %>
inherits value are not matching my UploadHandler.ashx.cs namespace that's the problem, now its fixed.
Thanks everyone.

How to download file via jQuery ajax and 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;

Categories

Resources