I have a problem with CKEditor. When the user paste an image with CTRL-V in the editor, I want to upload the image on the server, and replace all the base64 text in the src attribute of the image with the URL generated on the server.
I tried to upload the image in this way:
edit1.on('paste', function (evt) {
var data, name;
var copiedImage = evt.data.dataTransfer._.files[0] || null;
if (copiedImage && copiedImage.type.search('image/') > -1) {
data = copiedImage;
name = copiedImage.name;
var xhr = new XMLHttpRequest(),
fd = new FormData();
fd.append('file', data, name);
fd.append("upload_type", "ticket_image");
xhr.open('POST', 'uploadHandler.ashx', true);
xhr.onload = function (e) {
var response = xhr.response;
if (response.indexOf('ERROR') != -1) {
onAttachmentError(response);
}
else {
setTimeout(onUploadedImage(response), 1000);
}
}
xhr.send(fd);
}
}
This is the onUploadedImage called after the server method returns:
function onUploadedImage(response) {
var oFCKeditorDesc = CKEDITOR.instances.txtDescription;
if (oFCKeditorDesc) {
description = oFCKeditorDesc.getData().trim();
if (response) {
var objResp = JSON.parse(response);
var dom = document.createElement("DIV");
dom.innerHTML = description;
$(dom).find("img[src*='base64']").each(function () {
setTimeout($(this).attr('src', objResp.url), 1000);
});
oFCKeditorDesc.setData($(dom).html());
}
}
}
This is the server method that uploads the image on the database, and generates a servlet link to download the image
private string ProcessTicketTextImage(HttpContext context)
{
string fileAlias = context.Request.Files[0].FileName;
string fileName = string.Format("{0}{1}", string.Format("img_{0}", Guid.NewGuid().ToString().Replace("-", String.Empty)), Path.GetExtension(fileAlias));
string src = "";
string _imageservlet = helpsi.framework.core.Configurator.Instance.getAppSettingsValue("IMAGE_DOWNLOAD_SERVLET");
if (!string.IsNullOrEmpty(_imageservlet))
{
byte[] fileData = null;
using (var binaryReader = new BinaryReader(context.Request.Files[0].InputStream))
{
fileData = binaryReader.ReadBytes(context.Request.Files[0].ContentLength);
helpsi.framework.core.Common.Attachment att = new helpsi.framework.core.Common.Attachment();
att.DATE_LASTMODIFIEDDATE = DateTime.UtcNow;
att.DESC_FILENAME = fileName;
att.DESC_CONTENTTYPE = context.Request.Files[0].ContentType;
att.DESC_CONTENT = Convert.ToBase64String(fileData);
att.VALO_CONTENTLENGTH = context.Request.Files[0].ContentLength;
byte[] bodyContent = fileData;
long IdAttach = helpsi.framework.core.Common.Attachment.SaveAttachment(att, bodyContent);
if (IdAttach > 0)
src = string.Format(_imageservlet, IdAttach.ToString());
}
}
string _atchHTML = "{\n " +
" \"uploaded\": 1,\n" +
" \"fileName\": \"" + PageUtil.jsonString(fileName) + "\",\n" +
" \"url\": \"" + PageUtil.jsonString(src) + "\"\n" +
"}";
return _atchHTML;
}
The upload of the image works, the problem is that sometimes if I paste different images, the last image url is replaced in all the src attribute of the pasted images, even if the Xhr request is asynchronous: I tried with setTimeout before replace the image src, but it doesn't work. How can i solve this? Thanks
Related
I've created a method that reads .jpg files and displays them on my screen without extracting.
The var looks like this
var imageName = content.contentid + ".jpg";
content.contentid is too id number of the number + .jpg
But now I want that if there is, for example, a png or jfif file in the zip that it also just shows it.
How do I handle this in this method?
This is my code so far
private void getImage()
{
try
{
var folderName = "protocol-" + _protocol.id + "-" + _protocol.versionnr + ".zip";
var extractPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var zipPath = $"{extractPath}" + "/" + $"{folderName}";
var currentIndex = getCurrentIndex();
var content = _protocol.contents[currentIndex];
List<string> allowedExtensions = new List<string>() { "jpg", "png", "jfif" };
using (var archive = ZipFile.OpenRead(zipPath))
{
foreach (var pictureEntry in archive.Entries)
if (Path.GetFileNameWithoutExtension(pictureEntry.Name).Equals(content.contentid) && allowedExtensions.Contains(Path.GetExtension(pictureEntry.Name)))
{
byte[] buffer;
var length = pictureEntry.Length;
buffer = new byte[length];
pictureEntry.Open().Read(buffer, 0, (int)length);
myImage.Source = ImageSource.FromStream(() => new MemoryStream(buffer));
}
}
}
catch (Exception)
{
}
}
Well you can try this approach:
First define a List of extensions that you want to check against:
List<string> allowedExtensions = new List<string>() {"jpg", "png", "jfif" };
then change your if (pictureEntry.Name == imageName) for
if (Path.GetFileNameWithoutExtension(pictureEntry.Name) == content.contentid &&
allowedExtensions.Contains(Path.GetExtension(pictureEntry.Name)))
Also this line var imageName = content.contentid + ".jpg"; is innecesary as imageName didn't be used:
I am uploading multiple images to my folder asynchronously using XMLHttpRequest. After the all images are completely loaded to folder I need to send an email which contains these images in the email body part as well as attachment. My question is how do I check if all the images are completely uploaded to my folder. I have tried the following:
$scope.UploadFile = function (inputFile) {
var j = inputFile.length;
var filenames = [];
for (var i = 0; i < inputFile.length; i++) {
$scope.UploadFileIndividual(inputFile[i].file,
inputFile[i].file.name,
inputFile[i].file.type,
inputFile[i].file.size,
i, inputFile.length);
filenames[i] = inputFile[i].file.name;
j--;
}
if (j == 0)
{
$http({
method: 'POST',
url: '/RFQ/SendEmail/',
data: { RFQValues: $scope.RFQData, fileNames: filenames}
}).success(function (response, status, headers, config) {
if (response == true) {
window.location.href = '/CheckOut/ThankYou';
}
}).error(function (response, status, headers, config) {
// alert('Your Selection Not Added to Cart');
});
}
} ;
$scope.UploadFileIndividual = function (fileToUpload, name, type, size, index, fileArrayLength) {
var reqObj = new XMLHttpRequest();
//open the object and set method of call(get/post), url to call, isasynchronous(true/False)
reqObj.open("POST", "/RFQ/UploadFiles", true);
//set Content-Type at request header.For file upload it's value must be multipart/form-data
reqObj.setRequestHeader("Content-Type", "multipart/form-data");
//Set Other header like file name,size and type
reqObj.setRequestHeader('X-File-Name', name);
reqObj.setRequestHeader('X-File-Type', type);
reqObj.setRequestHeader('X-File-Size', size);
// send the file
reqObj.send(fileToUpload);
};
This is my controller method to upload images:
public virtual string UploadFiles(object obj)
{
try
{
var length = Request.ContentLength;
var bytes = new byte[length];
Request.InputStream.Read(bytes, 0, length);
var fileName = Request.Headers["X-File-Name"];
var fileSize = Request.Headers["X-File-Size"];
var fileType = Request.Headers["X-File-Type"];
string path = #"~\images\Client Images";
string subPath = System.Web.HttpContext.Current.Session["UserName"].ToString() + "_" + System.Web.HttpContext.Current.Session["UserId"].ToString();
string finalPath = Server.MapPath(path + #"\" + subPath);
if (!Directory.Exists(finalPath))
Directory.CreateDirectory(finalPath);
var saveToFileLoc = finalPath + #"\" + fileName;
// save the file.
var fileStream = new FileStream(saveToFileLoc, FileMode.Create, FileAccess.ReadWrite);
fileStream.Write(bytes, 0, length);
fileStream.Close();
var usrid = Convert.ToInt32(System.Web.HttpContext.Current.Session["UserId"].ToString());
using (DataContext _db = new DataContext())
{
int RFQId = _db.RFQDetailss.OrderByDescending(x => x.RFQId).Where(x => x.UserId == usrid && EntityFunctions.TruncateTime(x.RFQ_CreatedDate) == EntityFunctions.TruncateTime(DateTime.Now)).Select(y => y.RFQId).FirstOrDefault();
RFQClientImage objClientImage = new RFQClientImage();
objClientImage.RFQId = RFQId;
objClientImage.ImagePath = #"images\Client Images\" + subPath + #"\" + fileName;
_db.RFQClientImages.Add(objClientImage);
_db.SaveChanges();
}
return string.Format("{0} bytes uploaded", bytes.Length);
}
catch
{
return "";
}
}
I have then checked on js side if all files are sent for uploading and then in controller also I am checking if currently uploaded files exists in the folder by following code:
public JsonResult SendEmail(RFQFormInfo RFQValues, string[] fileNames)
{
bool IsMailSent = false;
try
{
string directoryPath = #"~\images\Client Images\";
string subDirectoryPath = System.Web.HttpContext.Current.Session["UserName"].ToString() + "_" + System.Web.HttpContext.Current.Session["UserId"].ToString() + #"\";
//string[] fileEntries = Directory.GetFiles(Server.MapPath(directoryPath + subDirectoryPath));
string targetPath = Server.MapPath(directoryPath + subDirectoryPath);
IsMailSent = checkifImageUploaded(RFQValues, getFilesList(targetPath), fileNames);
return Json(IsMailSent, JsonRequestBehavior.AllowGet);
}
catch
{
return Json(IsMailSent, JsonRequestBehavior.AllowGet);
}
}
public bool checkifImageUploaded(RFQFormInfo RFQValues, IEnumerable<string> fileEntries, string[] fileNames)
{
bool IsMailSent = false;
try
{
int counter = 0;
string directoryPath = #"~\images\Client Images\";
string subDirectoryPath = System.Web.HttpContext.Current.Session["UserName"].ToString() + "_" + System.Web.HttpContext.Current.Session["UserId"].ToString() + #"\";
string targetPath = Server.MapPath(directoryPath + subDirectoryPath);
foreach (string filename in fileNames)
{
var currentFile = Server.MapPath(directoryPath + subDirectoryPath + filename);
foreach(var file in fileEntries)
{
if (file.Equals(currentFile))
{
counter++;
break;
}
}
if (counter == fileNames.Length)
break;
}
if (counter == fileNames.Length)
{
IsMailSent = SendRFQMail(RFQValues, fileNames);
return IsMailSent;
}
else
checkifImageUploaded(RFQValues, getFilesList(targetPath), fileNames);
return IsMailSent;
}
catch
{
return IsMailSent;
}
}
public IEnumerable<string> getFilesList(string targetDirectory)
{
var fileEntries = Directory.EnumerateFiles(targetDirectory);
return fileEntries;
}
but my checkIfImageUploaded() function throws stack overflow exception. I understand it is because my code is ending up into infinite loop or recursion but what I don't understand is at what point is my code ending into infinite recursion and how to solve it.
Please help me out. Thanks in advance.
I am LinqToCsv and this tutorial to convert my data to a downloadable csv files.
WHAT HAVE I DONE :
I have created an action like the one shown below:
public FileResult GetReportCsvData(MyFilterModel model)
{
var data = _myService.GetMyData(model);
var fileName = String.Format("{0}_{1}_{2:yyyy_MMM_d}", Helpers.GetLoggedInUserName(), "Ad-Reports", DateTime.Today) + ".csv";
var outputFileDescription = new CsvFileDescription { SeparatorChar = ',', FirstLineHasColumnNames = true };
var cc = new CsvContext();
cc.Write(data, "c:/" + fileName, outputFileDescription);
return File("c:/" + fileName, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}
and using the following jquery I get my csv file:
exportCsv: function () {
var data = this.getFilters();
var url = '/MyController/GetReportCsvData';
var form = document.createElement('form');
form.action = url;
form.method = 'POST';
form.style.display = 'none';
for (i in data) {
if (data[i] != "") {
var inputElement = document.createElement('textarea');
inputElement.name = i;
inputElement.value = data[i];
form.appendChild(inputElement);
}
}
document.body.appendChild(form);
form.submit();
}
This works and I get the csv file with the download prompt.
WHAT DO I WANT
Here with the current code I have to save the file on my server (C:/filename) and then return its File object.
I do not want to save it on my server.
What changes do I have to make to achieve this ?
on "cc.Write" you write to disk, outputFileDescription is already a TextStream. So instead of saving it to disk first, and then reading it from disk with "File", just return the TextStream
I have a project wherein fileupload controls are generating dynamically. Using Json, I'm trying to save file in a directory asynchronously. I want to save files with filename using handler template in asp.net 4.0.
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: Sitepath + "Handler/FileUploader.ashx?filename="+strfiles,
secureuri: false,
fileElementClass: "multi",
dataType: "json",
async: false
});
I've added HTTPPostedFile's logic outside FileUploader class as it was throwing error in that.
public class FileUploader : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
string rt = "";
HttpContext.Current.Response.ContentType = "text/HTML";
string urlresponse = HttpContext.Current.Request.Url.ToString();
string tempfiles = "";
string filenames = "";
int convert = urlresponse.IndexOf(",");
urlresponse = urlresponse.Substring(convert + 1);
string[] filesArray = urlresponse.Split(',');
for (int i = 0; i < filesArray.Length; i++)
{
tempfiles = filesArray[i].ToString();
int lstIndex=tempfiles.LastIndexOf("\\");
filenames = filenames + "," + tempfiles.Substring(lstIndex + 1);
}
filenames = filenames.Substring(filenames.IndexOf(',') + 1);
HttpFileCollection uploads = HttpContext.Current.Request.Files;
string b = HttpContext.Current.Request.Url.ToString();
Hashtable hashtable = new Hashtable();
// Declare variable
string OrderFileName = String.Empty;
string OrderIDs =String.Empty;
string TempFolder = String.Empty;
if (HttpContext.Current.Session["OrderID"] != null)
{
OrderIDs = HttpContext.Current.Session["OrderID"].ToString();
string mapPath = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["DocPath"].ToString());
string mapPathUserId = mapPath + "\\" + HttpContext.Current.Session["UserID"];
///
var g = filenames.Split(',');
for (int t = 0; t < g.Length;t++ )
{
var h = g[t];
rt = filesArray[t].ToString();
if (Directory.Exists(mapPathUserId) == false)
{
Directory.CreateDirectory(mapPathUserId);
}
string mapPathCount = mapPathUserId + "/" + OrderIDs;
if (Directory.Exists(mapPathCount) == false)
{
//--------------Begin(Create Directory)----------------------------------------------------------------------------------//
Directory.CreateDirectory(mapPathCount);
//--------------End(Create Directory)----------------------------------------------------------------------------------//
}
TempFolder = mapPathUserId + "/" + "Temp";
if (Directory.Exists(TempFolder) == false)
{
//--------------Begin(Create Directory for temp folder)----------------------------------------------------------------------------------//
Directory.CreateDirectory(TempFolder);
//--------------End(Create Directoryfor temp folder)----------------------------------------------------------------------------------//
}
OrderFileName = h;
hashtable.Add(t.ToString(), OrderFileName);
var see = HttpContext.Current.Server.MapPath(TempFolder + "/" + OrderFileName);
}
Now, path is being created successfully, but file is not getting saved in specified directory. My code to save the file:
for (int i = 0; i < uploads.Count; i++)
{
HttpPostedFile upload = uploads[i];
if (Directory.Exists(mapPathUserId) == false)
{
Directory.CreateDirectory(mapPathUserId);
}
string mapPathCount = mapPathUserId + "/" + OrderIDs;
if (Directory.Exists(mapPathCount) == false)
{
//--------------Begin(Create Directory)----------------------------------------------------------------------------------//
Directory.CreateDirectory(mapPathCount);
//--------------End(Create Directory)----------------------------------------------------------------------------------//
}
/// Create Path for Temp Folder
TempFolder = mapPathUserId + "/" + "Temp";
if (Directory.Exists(TempFolder) == false)
{
//--------------Begin(Create Directory for temp folder)----------------------------------------------------------------------------------//
Directory.CreateDirectory(TempFolder);
//--------------End(Create Directoryfor temp folder)----------------------------------------------------------------------------------//
}
if (upload.ContentLength > 0)
{
if (upload.FileName.Contains(" "))
{
OrderFileName = upload.FileName.Replace(" ", "_");
}
else
{
OrderFileName = upload.FileName;
}
hashtable.Add(i.ToString(), OrderFileName);
upload.SaveAs(TempFolder + "/" + OrderFileName);
}
}
Please help.
You have to make sure you pass a right path, in the server. I would try mapping the path with the MapPath() function:
upload.SaveAs(Server.MapPath(TempFolder + "/" + OrderFileName));
public ActionResult GeneratePdf(int id)
{
var labelRepository = new LabelRepository();
var label = labelRepository.GetLabel(id);
if (String.IsNullOrEmpty(label.PDFLocation))
{
var action = Url.Content("~/Label/ViewPdf/" + id); //doc
Doc theDoc = new Doc();
string filename = Guid.NewGuid().ToString();
string path = Server.MapPath("~/" + filename + ".pdf");
theDoc.AddImageUrl("action");
theDoc.Save(path);
theDoc.Clear();
label.PDFLocation = path;
labelRepository.Save();
return base.File(path, "application/pdf");
}
else
{
return base.File(label.PDFLocation, "application/pdf");
}
}
This won't add my image url so my pdf won't open up so I can see it. Any ideas?-
In the example here, a complete URL is being passed to the AddImageUrl() function, not a fragment of an URL, as your example shows.
Perhaps you need a call to RouteUrl() so that you can get a complete Url to pass to your AddImageUrl() method?