My Image Won't Add C# - c#

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?

Related

Upload image in CKEditor and replace base64 with generated URL

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

Adding an optional attachment to a asp.net c# form

I have a problem with some code developed by a supplier. Unfortunately the supplier is no longer available, so I'm trying to fix my problem myself!
This is my code:
public ActionResult ReportaProblem(string title, string description, string url)
{
tblReportProblem feature = new tblReportProblem();
var path = "";
feature.Title = title;
feature.Description = description;
feature.DateTime = DateTime.UtcNow;
feature.UserId = AppConfig.LoginId;
HttpPostedFileBase fu = Request.Files["fuScreenCapture"];
if (fu.FileName != "")
{
string newName = "";
var filename = "";
filename = Path.GetFileName(fu.FileName).ToLower();
newName = DateTime.Now.ToString("MMddyyHHmmss") + filename;
path = Path.Combine(Server.MapPath(Constants.Paths.ProblemImagePath + newName));
fu.SaveAs(path);
feature.FileName = newName;
}
if (_IProject.AddReportProblem(feature))
{
TempData["success"] = Constants.ReportProblemSuccess;
}
Attachment attachment = new Attachment(path);
ReportProblemEmailToAdmin(title, description, url, attachment);
return RedirectToAction("ReportaProblem");
}
Basically it allows a user to report a problem in the application. It includes the ability to add an attachment (i.e. a screen image). The problem is that if the user doesn't attach a file, I get:
Server Error in '/' Application.
The parameter 'fileName' cannot be an empty string.
Parameter name: fileName
How do I allow the user to submit the problem report without an attachment?
Thanks, David.
You have to use the fileuploadcontrol API in your C# code, and this control must be there in your aspx page. For example, you should have markup like below in your aspx page ( the id can be anything you want).
Since you have not provided any markup, so I have assumed that the id of file upload control is fileUploadControl1, and all code is based on this assumption.
Markup for file upload control
<asp:FileUpload id="fileUploadConrol1" runat="server" />
Then, your C# code should be like below.
Note that you need to first check if any file has been posted by
checking the boolean flag fileUploadConrol1.HasFile and if true
then you do your attachment logic else you skip the attachment
logic.
Also, make sure that when attachment parameter is null in method
ReportProblemEmailToAdmin then its appropriately handled.
C# code using API of above file upload control
public ActionResult ReportaProblem(string title, string description, string url)
{
tblReportProblem feature = new tblReportProblem();
var path = "";
feature.Title = title;
feature.Description = description;
feature.DateTime = DateTime.UtcNow;
feature.UserId = AppConfig.LoginId;
//fileUploadConrol1 is id of file upload control in your aspx markup
if(fileUploadConrol1.HasFile)
{
//this line below is not needed
//HttpPostedFileBase fu = Request.Files["fuScreenCapture"];
//if (fu.FileName != "")
//{
string newName = "";
var filename = "";
filename = Path.GetFileName(fileUploadControl1.FileName).ToLower();
newName = DateTime.Now.ToString("MMddyyHHmmss") + filename;
path = Path.Combine(Server.MapPath(Constants.Paths.ProblemImagePath + newName));
fileUploadControl1.SaveAs(path);
feature.FileName = newName;
//}
}
if (_IProject.AddReportProblem(feature))
{
TempData["success"] = Constants.ReportProblemSuccess;
}
Attachment attachment = null;
if(path!= string.Empty)
{
attachment = new Attachment(path);
}
ReportProblemEmailToAdmin(title, description, url, attachment);
return RedirectToAction("ReportaProblem");
}
Alternate solution if you are using html file control and not asp fileupload control
Use the C# code below, if you are using html file control rather than asp fileupload control. (NOTE: The above solution would work only if you have asp file upload file control. Use this alternate solution in your case).
public ActionResult ReportaProblem(string title, string description, string url)
{
tblReportProblem feature = new tblReportProblem();
var path = "";
feature.Title = title;
feature.Description = description;
feature.DateTime = DateTime.UtcNow;
feature.UserId = AppConfig.LoginId;
HttpPostedFile fu = null;
if (Request.Files.Count > 0 )
{
//get the posted file
fu = Request.Files[0];
//apply logic to posted file
if(fu!=null) {
string newName = "";
var filename = "";
filename = Path.GetFileName(fu.FileName).ToLower();
newName = DateTime.Now.ToString("MMddyyHHmmss") + filename;
path = Path.Combine(Server.MapPath(Constants.Paths.ProblemImagePath + newName));
fu.SaveAs(path);
feature.FileName = newName;
}
}
if (_IProject.AddReportProblem(feature))
{
TempData["success"] = Constants.ReportProblemSuccess;
}
Attachment attachment = null;
if(path!= string.Empty)
{
attachment = new Attachment(path);
}
ReportProblemEmailToAdmin(title, description, url, attachment);
return RedirectToAction("ReportaProblem");
}

How to create PDF Report with data from code in list form, not directly from database with Microsoft Report Viewer

I am using Microsoft.Report.Viewer for generate PDF in my ASP .NET WEB API application. So far when my report get the data directly from database, there is no problem. The problem is, when I try to create a report with subreport within and the subreport data is got from code in a list form, I didn't get the expected result. What I do is create a report with subreport from this tutorial. But when I generate the PDF, what I get is this message .
Here is my code :
My Web API to generate the PDF :
[Route("GeneratePDFForDailyProgram")]
[HttpGet]
[AllowAnonymous]
public async Task<IHttpActionResult> GeneratePDFForDailyProgram(int id) {
string guid = Guid.NewGuid().ToString();
string fileName = string.Concat("Booking_No" + Convert.ToString(id) + "_" + guid.ToUpper() + ".pdf");
string filePath = HttpContext.Current.Server.MapPath("~/Content/Temp/" + fileName);
string name = Request.RequestUri.GetLeftPart(UriPartial.Authority) + System.Configuration.ConfigurationManager.ConnectionStrings[System.Configuration.ConfigurationManager.AppSettings["CUSTOMPORT"]];
string name2 = Request.GetRequestContext().VirtualPathRoot;
List<TourDestination> destination = new List<TourDestination>();
TourTransactionSummaryViewModel summaryViewModel = new TourTransactionSummaryViewModel();
try {
//summaryViewModel = await CalcSummaryViewModel(transaction, summaryViewModel, db);
summaryViewModel.DailyPrograms = DailyProgram(id);
destination = TourDestination(summaryViewModel.DailyPrograms);
List < Movement > movementList = summaryViewModel.DailyPrograms.FirstOrDefault().Movements.ToList();
Reports.ReportGenerator.GeneratePDFForDailyProgram(summaryViewModel.DailyPrograms, destination, filePath);
//await Reports.ReportGenerator.GeneratePDFForMovement(movementList, filePath);
HttpResponseMessage result = null;
result = Request.CreateResponse(HttpStatusCode.OK);
result.Content = new StreamContent(new FileStream(filePath, FileMode.Open));
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = fileName;
result.Dispose();
string convertedFilePath = filePath.Replace(#"\\", #"\");
} catch (Exception ex) {
return BadRequest(ex.Message);
}
return Ok(name + name2 + "/Content/Temp/" + fileName);
}
As you can see from the code above, I use GeneratePDFForDailyProgram method to generate the PDF.
Here my GeneratePDFForDailyProgram method :
public static bool GeneratePDFForDailyProgram(TourTransactionSummaryViewModel.DailyProgram[] dailyPrograms, List<TourDestination> destination , string filePath) {
try {
string binPath = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "bin");
var assembly = Assembly.Load(System.IO.File.ReadAllBytes(binPath + "\\TripPlannerAPI.dll"));
using (Stream stream = assembly.GetManifestResourceStream(DailyProgramReport)) {
var viewer = new ReportViewer();
viewer.LocalReport.EnableExternalImages = true;
viewer.LocalReport.LoadReportDefinition(stream);
Warning[] warnings;
string[] streamids;
string mimeType;
string encoding;
string filenameExtension;
viewer.LocalReport.SubreportProcessing += new Microsoft.Reporting.WebForms.SubreportProcessingEventHandler(LocalReport_SubreportProcessing);
viewer.LocalReport.DataSources.Add(new ReportDataSource("DailyProgram", dailyPrograms));
byte[] bytes = viewer.LocalReport.Render(
"PDF", null, out mimeType, out encoding, out filenameExtension,
out streamids, out warnings);
using (FileStream fs = new FileStream(filePath, FileMode.Create)) {
fs.Write(bytes, 0, bytes.Length);
fs.Flush();
}
stream.Flush();
}
} catch (Exception ex) {
return false;
}
return true;
}
To run the SubReport, I use the eventhandler code :
private static void LocalReport_SubreportProcessing(object sender, SubreportProcessingEventArgs e) {
DateTime movementDate = Convert.ToDateTime(e.Parameters[0].Values[0]);
TourTransactionsController controller = new TourTransactionsController();
var movement = controller.Movements();
List<Movement> movementList = new List<Movement>();
movementList.Add(new Movement {
Destination = "TEST",
MovementDescription = "TEST",
DateTime = Convert.ToDateTime("2017-09-25") //HARDCODE FOR TEST
});
e.DataSources.Clear();
e.DataSources.Add(new Microsoft.Reporting.WebForms.ReportDataSource() {
Name = "DSMovements",
Value = movementList
});
//throw new NotImplementedException();
}
What I did try :
Check the sub report name, and change it from report name to report file url. Still get the same message.
Generate the Sub Report directly, not from the main report. The subreport is successfully generated.
PS : When I debug my code, and put a breakpoint in my event handler LocalReport_SubreportProcessing the breakpoint is not hitting while debugging
My Questions are :
Why my breakpoint on the eventhandler is not hitting while debugging ?
Is it possible that eventhandler which is not hitting while debugging, could be the reason I got the message The subreport 'MovementReport' could not be
found at the specified location MovementReport.
Please verify that the subreport has been
published and that the name is correct. ?
Is there any other way for me to create a main report with data from db, and the subreport with data from code in list form ?
Any help is appreciated.

HTTP Header Issue

I'm working on MVC5 project on .NET 4.5.3. I have View with #Html.BeginForm and FormMethod.Post this view calls [HttpPost] ActionResult. In the Controller i get necessary ID's from the submitted form and then pass them for exporting.
[HttpPost]
public ActionResult PrepareForExport()
{
ExportService export = new ExportService();
if (Request.Form["button"] != null)
{
string selected = Request.Form["button"].ToString();
export.GeneratePdf(ptoRequestsService.GetByID(Convert.ToInt32(selected)));
}
else if (Request.Form["toExport"] != null)
{
List<PtoRequest> ptoListForExport = new List<PtoRequest>();
string selectedItems = Request.Form["toExport"].ToString();
string[] selectedList = selectedItems.Split(',');
foreach (var pto in selectedList)
{
ptoListForExport.Add(ptoRequestsService.GetByID(Convert.ToInt32(pto)));
}
export.GenerateZip(ptoListForExport);
}
return RedirectToAction("Requests" + LoggedUser.ID);
}
And in the ExportService class i have this export method.
public void GenerateZip(List<PtoRequest> approvedPtos)
{
byte[] pdfContent = null;
string dateFormat = "yyyy-MM-dd";
string filePath = null;
if (!Directory.Exists(HttpContext.Current.Server.MapPath(#"~/Files/PdfFiles/")))
{
Directory.CreateDirectory(HttpContext.Current.Server.MapPath("~/Files/PdfFiles/"));
filePath = HttpContext.Current.Server.MapPath("~/Files/PdfFiles/");
}
else
{
filePath = HttpContext.Current.Server.MapPath("~/Files/PdfFiles/");
}
foreach (var Pto in approvedPtos)
{
pdfContent = FillPdfTemplate(Pto);
string fileName = Pto.User.FirstName + " " + Pto.User.LastName + "_" + Pto.StartDate.ToString(dateFormat) + ".pdf";
string fileDirectory = filePath + fileName;
using (FileStream fs = new FileStream(fileDirectory, FileMode.OpenOrCreate))
{
fs.Write(pdfContent, 0, pdfContent.Length);
}
}
string zipName = String.Format("Report_{0}.zip", DateTime.Now.ToString("yyyy-mm-dd-HHmmss"));
string zipFile = filePath + zipName;
using (ZipFile zip = new ZipFile())
{
zip.AddDirectory(filePath);
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.BufferOutput = false;
HttpContext.Current.Response.ContentType = "application/zip";
HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=" + zipName);
zip.Save(HttpContext.Current.Response.OutputStream);
HttpContext.Current.Response.Write(zip.ToString());
HttpContext.Current.Response.End();
Directory.Delete(filePath, true);
}
}
Everything works fine, but when my method complete the job i got exception with code 500. I do my googling to understand my problem and it is something like this 1. I understand that the problem is in HttpHeader but did not understand how to solve it in my case. Then i tried the solution with if (!Response.IsRequestBeingRedirected) but i still got this exception. After this I tried to return ZipFile from GenerateZip Method and instead calling Response in ExportService class to call it at Controller, but i still got this Error. I have an idea to remove [HttpPost] attribute and to take my ID's in other way but my point is to do it that way. Can anyone point me in any direction to solving this? What is the right decision, where should i call Response for this case, is it option to write jQuery script to prevent submitting form in .cshtml?
You are calling HttpContext.Current.Response.End(); in your GenerateZip method and then attempting to Redirect the user in the ControllerAction. This is causing your "Headers cannot be written after response is sent" error. Instead of that, return a byte array or Stream object (FileStream?) from the GenerateZip method and return a FileResult in the Action. Redirecting the user after the file download can (only?) be achieved using JavaScript. Here is an example. How to return a FileResult AND RedirectToAction in ASP.NET MVC

How to know when a method finish in controller

I have a problem with this method, i want to return a PDF file and when the method it's over i want to delete de file from the directory.
public ActionResult DescargaPdfCompara(string id)
{
var rutaPdf = string.Empty;
var type = "application/pdf";
try
{
DateTime ahora = DateTime.Now;
var numeroAleatorio = new Random();
int numeroRandomico = numeroAleatorio.Next(100000000, 1000000000);
string Ruta = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"Reportes\" + Convert.ToString(ahora.Year + ahora.Month + ahora.Day + ahora.Hour + ahora.Minute + ahora.Second + numeroRandomico) + ".pdf");
var result = SimuModel.ObtenerSabanaReporteComparativo(id);
var resumen = SimuModel.ObtenerPreExcel(result);
SimuModel.GenerarPdfCompa(result, resumen, Ruta);
rutaPdf = Ruta;
return File(rutaPdf, type);
}
catch (Exception e)
{
throw e;
}
finally
{
System.IO.File.Delete(rutaPdf);
}
}
In the finally i delete the file but i got an error because the method can't find the file, for some reason the method delete the file before return it.
PD: Sorry for my english, i'm from Chile.
Thanks fro your answers!
You can use System.IO.File.ReadAllBytes to read all the file contents to memory, then delete the file and return the contents with another overload of Controller.File method:
public ActionResult GetFile()
{
var fileName = Path.GetTempFileName();
System.IO.File.WriteAllText(fileName, "Hola, Chile!");
var bytes = System.IO.File.ReadAllBytes(fileName);
System.IO.File.Delete(fileName);
return File(bytes, "text/plain", "file.txt");
}
Change return type ContentResult
remove finally section.
public ContentResult DescargaPdfCompara(string id)
{
var rutaPdf = string.Empty;
var type = "application/pdf";
try
{
DateTime ahora = DateTime.Now;
var numeroAleatorio = new Random();
int numeroRandomico = numeroAleatorio.Next(100000000, 1000000000);
string Ruta = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"Reportes\" + Convert.ToString(ahora.Year + ahora.Month + ahora.Day + ahora.Hour + ahora.Minute + ahora.Second + numeroRandomico) + ".pdf");
var result = SimuModel.ObtenerSabanaReporteComparativo(id);
var resumen = SimuModel.ObtenerPreExcel(result);
SimuModel.GenerarPdfCompa(result, resumen, Ruta);
rutaPdf = Ruta;
return Content(rutaPdf, type);
}
catch (Exception e)
{
throw e;
}
}

Categories

Resources