HtmlAgilityPack : Is there a better way to write this - c#

I recently started experimenting with HtmlAgilityPack, and the following code is working for what I want to achieve.
But since I just started exploring this, I was wondering if there was a better way then using so many PreviousSibling tags
var Application_Html = #"https://wiki.profittrailer.com/doku.php?id=application.properties";
HtmlWeb Internet_Load_Connection = new HtmlWeb();
var Application_Html_Loaded = Internet_Load_Connection.Load(Application_Html);
var Wiki_Application_Part_Loaded = Application_Html_Loaded.DocumentNode.SelectSingleNode("//div[#class ='dw-content']");
var divs = Application_Html_Loaded.DocumentNode.Descendants("div").Where(node => node.GetAttributeValue("class", "").Equals("level5")).Where(node => node.ParentNode.GetAttributeValue("class", "").Equals("dw-content")).ToList();
foreach (var s in divs)
{
if (s.InnerText.IndexOf(" ") > 0)
{
if (s.PreviousSibling.PreviousSibling.Id.Contains("default_api") || s.PreviousSibling.PreviousSibling.Id.Contains("trading_api"))
{
textBox1.AppendText(s.PreviousSibling.PreviousSibling.PreviousSibling.PreviousSibling.PreviousSibling.PreviousSibling.Id + "\n");
textBox1.AppendText(s.PreviousSibling.PreviousSibling.PreviousSibling.PreviousSibling.PreviousSibling.PreviousSibling.InnerText + "\n");
textBox1.AppendText(s.ChildNodes[3].InnerText + "\n");
textBox1.AppendText("\n");
textBox1.AppendText(s.PreviousSibling.PreviousSibling.Id + "\n");
textBox1.AppendText(s.PreviousSibling.PreviousSibling.InnerText + "\n");
textBox1.AppendText(s.ChildNodes[3].InnerText + "\n");
textBox1.AppendText("\n");
}
else
{
textBox1.AppendText(s.PreviousSibling.PreviousSibling.Id + "\n");
textBox1.AppendText(s.PreviousSibling.PreviousSibling.InnerText + "\n");
textBox1.AppendText(s.ChildNodes[3].InnerText + "\n");
textBox1.AppendText("\n");
}
}
}
The idea behind this is to scrape the wiki to see if anything has changed and if so to update/notify me if changes are needed.
Example html piece for reference
<h5 id="tradingexchange">trading.exchange</h5>
<div class="level5">
<pre class="code file java">trading.<span class="me1">exchange</span> <span
class="sy0">=</span> BITTREX</pre>
<p>
Use to set the exchange you want the bot to connect to. Possible values
(POLONIEX, BITTREX, BINANCE).
Must be in CAPITALS.
</p>
<hr />
</div>
all is in the div class="dw-content" which I extract first
h5 id is needed to check if new option are added
h5 innertext is need to check the formatting
p innertext to check if the description is updated or not

Related

Adding Newline in string for HTML email body

I'm trying to generate an email with some basic formatting based on labels in a FormView. I'm going the route of Process.Start("mailto:... instead of System.Net.Mail so the email opens up in the default email client to give the user a chance to edit To: CC: etc without making a new form just to handle that. I've got the following code-behind to handle an "Email Form" button for emailing the URL of the webform.
protected void fvBF_ItemCommand(object sender, FormViewCommandEventArgs e)
{
if (e.CommandName == "Email")
{
Label lblBFID = (Label)fvBookingForm.FindControl("lblBFID");
Label lblProjectID = (Label)fvBookingForm.FindControl("lblProjectNum");
Label lblProjectName = (Label)fvBookingForm.FindControl("lblProjectName");
Label lblReleaseName = (Label)fvBookingForm.FindControl("lblReleaseName");
Label lblPMName = (Label)fvBookingForm.FindControl("lblPM");
String strReleaseName = String.IsNullOrEmpty(lblReleaseName.Text) ? "[Description]" : lblReleaseName.Text;
String pmFirst = lblPMName.Text.ToString().Split()[0];
String pmLast = lblPMName.Text.ToString().Split()[1];
String strSubject = "BF " + lblBFID.Text + " - " + lblProjectName.Text + " - Release " + strReleaseName;
String strBody = "A Booking Form for Project #"+ lblProjectID.Text + " - " + lblProjectName.Text +
" - Release " + strReleaseName + " has been created or modified. \n\n" + Request.Url.ToString();
Process.Start("mailto:" + pmFirst + "." + pmLast + "#company.com?subject=" +
HttpUtility.HtmlAttributeEncode(strSubject) + "&body=" +
HttpUtility.HtmlAttributeEncode(strBody).Replace("\n", Environment.NewLine));
}
}
However, when the email is generated, there are no line breaks in the body between the "A Booking Form...." sentence and the URL. I've tried putting Environment.NewLine directly in the string.
...created or modified. " + Environment.Newline + Environment.NewLine + Request.Url.ToString();
Which basically gives me the same results. I've tried replacing the \n with <br /> which doesn't add the line break and for some reason, doesn't display the URL either. I can only guess that the problem has to do with the HtmlAttributeEncode() and getting it to parse the NewLine properly. Is there something I'm missing here?
You might want to try .Replace("\r\n", "<br />") on the body after you have done your encoding of the body.
You should probably use StringBuilder here instead of String.
You can then do the following:
StringBuilder builder = new StringBuilder();
builder.AppendLine(string.Format("A Booking Form for Project #{0} - {1}",lblProjectID.Text, lblProjectName.Text));
builder.AppendLine(string.Format(" - Release {0} has been created or modified.", strReleaseName));
builder.AppendLine();
builder.AppendLine(Request.Url.ToString());
String strBody = builder.ToString();
You can also include (char)10 and (char)13 in your string creation. e.g.:
string.Format("First Line{0}{1}Second Line", (char)10, (char)13);
Model.Message = "my message \n second message";
then add this style to string tag style="white-space: pre-line;"
example <h3 style="white-space: pre-line;">#Model.Message</h3>

File Size Validation [duplicate]

Is there any way to check file size before uploading it using JavaScript?
Yes, you can use the File API for this.
Here's a complete example (see comments):
document.getElementById("btnLoad").addEventListener("click", function showFileSize() {
// (Can't use `typeof FileReader === "function"` because apparently it
// comes back as "object" on some browsers. So just see if it's there
// at all.)
if (!window.FileReader) { // This is VERY unlikely, browser support is near-universal
console.log("The file API isn't supported on this browser yet.");
return;
}
var input = document.getElementById('fileinput');
if (!input.files) { // This is VERY unlikely, browser support is near-universal
console.error("This browser doesn't seem to support the `files` property of file inputs.");
} else if (!input.files[0]) {
addPara("Please select a file before clicking 'Load'");
} else {
var file = input.files[0];
addPara("File " + file.name + " is " + file.size + " bytes in size");
}
});
function addPara(text) {
var p = document.createElement("p");
p.textContent = text;
document.body.appendChild(p);
}
body {
font-family: sans-serif;
}
<form action='#' onsubmit="return false;">
<input type='file' id='fileinput'>
<input type='button' id='btnLoad' value='Load'>
</form>
Slightly off-topic, but: Note that client-side validation is no substitute for server-side validation. Client-side validation is purely to make it possible to provide a nicer user experience. For instance, if you don't allow uploading a file more than 5MB, you could use client-side validation to check that the file the user has chosen isn't more than 5MB in size and give them a nice friendly message if it is (so they don't spend all that time uploading only to get the result thrown away at the server), but you must also enforce that limit at the server, as all client-side limits (and other validations) can be circumvented.
Using jquery:
$('#image-file').on('change', function() {
console.log('This file size is: ' + this.files[0].size / 1024 / 1024 + "MiB");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<form action="upload" enctype="multipart/form-data" method="post">
Upload image:
<input id="image-file" type="file" name="file" />
<input type="submit" value="Upload" />
</form>
Works for Dynamic and Static File Element
Javascript Only Solution
function validateSize(input) {
const fileSize = input.files[0].size / 1024 / 1024; // in MiB
if (fileSize > 2) {
alert('File size exceeds 2 MiB');
// $(file).val(''); //for clearing with Jquery
} else {
// Proceed further
}
}
<input onchange="validateSize(this)" type="file">
It's pretty simple.
const oFile = document.getElementById("fileUpload").files[0]; // <input type="file" id="fileUpload" accept=".jpg,.png,.gif,.jpeg"/>
if (oFile.size > 2097152) // 2 MiB for bytes.
{
alert("File size must under 2MiB!");
return;
}
No Yes, using the File API in newer browsers. See TJ's answer for details.
If you need to support older browsers as well, you will have to use a Flash-based uploader like SWFUpload or Uploadify to do this.
The SWFUpload Features Demo shows how the file_size_limit setting works.
Note that this (obviously) needs Flash, plus the way it works is a bit different from normal upload forms.
If you're using jQuery Validation, you could write something like this:
$.validator.addMethod(
"maxfilesize",
function (value, element) {
if (this.optional(element) || ! element.files || ! element.files[0]) {
return true;
} else {
return element.files[0].size <= 1024 * 1024 * 2;
}
},
'The file size can not exceed 2MiB.'
);
I made something like that:
$('#image-file').on('change', function() {
var numb = $(this)[0].files[0].size / 1024 / 1024;
numb = numb.toFixed(2);
if (numb > 2) {
alert('to big, maximum is 2MiB. You file size is: ' + numb + ' MiB');
} else {
alert('it okey, your file has ' + numb + 'MiB')
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<input type="file" id="image-file">
Even though the question is answered, I wanted to post my answer. Might come handy to future viewers.You can use it like in the following code.
document.getElementById("fileinput").addEventListener("change",function(evt) {
//Retrieve the first (and only!) File from the FileList object
var f = evt.target.files[0];
if (f) {
var r = new FileReader();
r.onload = function(e) {
var contents = e.target.result;
alert("Got the file\n" +
"name: " + f.name + "\n" +
"type: " + f.type + "\n" +
"size: " + f.size + " bytes\n" +
"starts with: " + contents.substr(1, contents.indexOf("\n"))
);
if (f.size > 5242880) {
alert('File size Greater then 5MiB!');
}
}
r.readAsText(f);
} else {
alert("Failed to load file");
}
})
<input type="file" id="fileinput" />
I use one main Javascript function that I had found at Mozilla Developer Network site https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications, along with another function with AJAX and changed according to my needs. It receives a document element id regarding the place in my html code where I want to write the file size.
<Javascript>
function updateSize(elementId) {
var nBytes = 0,
oFiles = document.getElementById(elementId).files,
nFiles = oFiles.length;
for (var nFileId = 0; nFileId < nFiles; nFileId++) {
nBytes += oFiles[nFileId].size;
}
var sOutput = nBytes + " bytes";
// optional code for multiples approximation
for (var aMultiples = ["K", "M", "G", "T", "P", "E", "Z", "Y"], nMultiple = 0, nApprox = nBytes / 1024; nApprox > 1; nApprox /= 1024, nMultiple++) {
sOutput = " (" + nApprox.toFixed(3) + aMultiples[nMultiple] + ")";
}
return sOutput;
}
</Javascript>
<HTML>
<input type="file" id="inputFileUpload" onchange="uploadFuncWithAJAX(this.value);" size="25">
</HTML>
<Javascript with XMLHttpRequest>
document.getElementById('spanFileSizeText').innerHTML=updateSize("inputFileUpload");
</XMLHttpRequest>
Cheers
JQuery example provided in this thread was extremely outdated, and google wasn't helpful at all so here is my revision:
<script type="text/javascript">
$('#image-file').on('change', function() {
console.log($(this)[0].files[0].name+' file size is: ' + $(this)[0].files[0].size/1024/1024 + 'Mb');
});
</script>
I ran across this question, and the one line of code I needed was hiding in big blocks of code.
Short answer: this.files[0].size
By the way, no JQuery needed.
You can try this fineuploader
It works fine under IE6(and above), Chrome or Firefox
I use this script to validate file type and size
var _validFilejpeg = [".jpeg", ".jpg", ".bmp", ".pdf"];
function validateForSize(oInput, minSize, maxSizejpeg) {
//if there is a need of specifying any other type, just add that particular type in var _validFilejpeg
if (oInput.type == "file") {
var sFileName = oInput.value;
if (sFileName.length > 0) {
var blnValid = false;
for (var j = 0; j < _validFilejpeg.length; j++) {
var sCurExtension = _validFilejpeg[j];
if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length)
.toLowerCase() == sCurExtension.toLowerCase()) {
blnValid = true;
break;
}
}
if (!blnValid) {
alert("Sorry, this file is invalid, allowed extension is: " + _validFilejpeg.join(", "));
oInput.value = "";
return false;
}
}
}
fileSizeValidatejpeg(oInput, minSize, maxSizejpeg);
}
function fileSizeValidatejpeg(fdata, minSize, maxSizejpeg) {
if (fdata.files && fdata.files[0]) {
var fsize = fdata.files[0].size /1024; //The files property of an input element returns a FileList. fdata is an input element,fdata.files[0] returns a File object at the index 0.
//alert(fsize)
if (fsize > maxSizejpeg || fsize < minSize) {
alert('This file size is: ' + fsize.toFixed(2) +
"KB. Files should be in " + (minSize) + " to " + (maxSizejpeg) + " KB ");
fdata.value = ""; //so that the file name is not displayed on the side of the choose file button
return false;
} else {
console.log("");
}
}
}
<input type="file" onchange="validateForSize(this,10,5000);" >
If you set the Ie 'Document Mode' to 'Standards' you can use the simple javascript 'size' method to get the uploaded file's size.
Set the Ie 'Document Mode' to 'Standards':
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
Than, use the 'size' javascript method to get the uploaded file's size:
<script type="text/javascript">
var uploadedFile = document.getElementById('imageUpload');
var fileSize = uploadedFile.files[0].size;
alert(fileSize);
</script>
It works for me.
Simple way is
const myFile = document.getElementById("fileUpload").files[0];
if (myFIle.size > 2097152) // 2 MiB for bytes.
{
alert("File size must under 2MiB!");
return;
}

Render fusionchart with Mvc3 and Razor engine

Since yesterday, I try to run a sample of code to display a chart with FusionCharts and Mvc3 Razor and nothing works. Please.... help!!! :)
Here is what I have done:
I took the projet from Libero. here
After that, I used the project convertor here to upgrade the project from Mvc2 to Mvc3.
When I try to run to code (F5 and show the result in browser), that works fine; all graphics are displayed correctly.
If I just create a new view with razor (.cshtml) instead of the current .aspx (replacing a view from the old syntax to the new razor) and I try to displayed the same graphic, the page is displayed correctly but without graphic. When I look into the page source with firebug or any other tools, no code is behind the scene. I also don't have any errors while looking with the Web Developer tool in Firefox.
I just tried to add a Html.Raw in front of the code that generate the javascript to not encode the output and I have the same result. Also trying with returning HtmlString but again same result; no graphic is displayed.
The key to don't miss in this problem is that if I try the exact same code but with an .aspx file, all is correct.
In .aspx, the code looks like this:
<%=Html.FChart("Chart01", ViewData["MyChart"], 600, 400)%>
And in .cshtml:
#{Html.FChart("Chart01", ViewData["MyChart"], 600, 400); }
And finally, the html helper to generate this bunch of code:
private static string RenderChart(string controlId, string xmlData, FusionChartBase chart, int width, int height)
{
String sControlId = controlId;
String sJsVarId = "_lib_JS_" + controlId;
String sDivId = "_lib_DIV_" + controlId;
String sObjId = "_lib_OBJ_" + controlId;
String sWidth = width.ToString();
String sHeight = height.ToString();
StringBuilder oBuilder = new StringBuilder();
oBuilder.AppendLine(#"<div id=""" + sDivId + #""" align=""center""></div>");
oBuilder.AppendLine(#"<script type=""text/javascript"">");
oBuilder.AppendLine(#"var " + sControlId + #" = (function() {");
oBuilder.AppendLine(#" return {");
oBuilder.AppendLine(#" containerId: '" + sDivId + "',");
oBuilder.AppendLine(#" xmlData: '',");
oBuilder.AppendLine(#" chartType: '',");
oBuilder.AppendLine(#" showChart: function() {");
oBuilder.AppendLine();
oBuilder.AppendFormat(#" var chartURL = '{0}' + this.chartType.replace('Chart', '{1}');", UrlSWF, SufixSWF);
oBuilder.AppendLine(#" var " + sJsVarId + #" = new FusionCharts(chartURL, """ + sObjId + #""", """ + sWidth + #""", """ + sHeight + #""");");
oBuilder.AppendLine(#" " + sJsVarId + #".setDataXML(this.xmlData);");
oBuilder.AppendLine(#" " + sJsVarId + #".render(""" + sDivId + #""");");
oBuilder.AppendLine(#" }");
oBuilder.AppendLine(#" }");
oBuilder.AppendLine(#"})();");
oBuilder.AppendLine(#"setTimeout(function(){");
oBuilder.AppendLine(#" " + sControlId + #".xmlData = """ + xmlData.Replace(#"""", #"'") + #""";");
oBuilder.AppendLine(#" " + sControlId + #".chartType = """ + chart.ChartType + #""";");
oBuilder.AppendLine(#" " + sControlId + #".showChart();");
oBuilder.AppendLine(#"},0);");
oBuilder.AppendLine(#"</script>");
return oBuilder.ToString();
}
I don't know if I must set some configuration options in the web.config or what I don't understand in the behavior of Mvc2 compare to Mvc3, but it's very frustrating.
If you have any idea, a big thanx in advance.
It should be #Html.FChart("Chart01", ViewData["MyChart"], 600, 400) instead of #{Html.FChart("Chart01", ViewData["MyChart"], 600, 400); }
FusionCharts provides a .NET library which makes rendering charts a one liner - read through the FusionCharts Documentation.
They have a recent tutorial up on their blog - JavaScript Charts with ASP.NET (C#) Using FusionCharts XT

AJAX javascript not firing asp.net c#

When I add new controls to my web application, the javascript does not fire. I've tried many solutions, but none of them work. Specifically, the accordion/accordion pane from the AJAX Control Toolkit does not slide up/down. Also the FileUploadProgress control from Obout uses javascript functions which do not fire. If I open a new web application project and try all this, it works just fine. My project is quite large so I cannot start from scratch. Can someone please tell me what could be wrong with my project? I have no errors. The javascript simply does not fire. Please help. I am using asp.net c#.
EDIT:
Here is the code for file upload progress control. I do have alert statements but they do not fire.
<script type="text/JavaScript">
function Clear() {
alert("here1");
document.getElementById("<%= uploadedFiles.ClientID %>").innerHTML = "";
}
function ClearedFiles(fileNames) {
alert("here2");
alert("Cleared files with bad extensions:\n\n" + fileNames);
}
function Rejected(fileName, size, maxSize) {
alert("here3");
alert("File " + fileName + " is rejected \nIts size (" + size + " bytes) exceeds " + maxSize + " bytes");
}
</script>
<input type="file" name="myFile1" runat="server"/><br/>
<input type="file" name="myFile2" runat="server"/><br/>
<input type="file" name="myFile3" runat="server"/><br/>
<input type="submit" value="submit" name="mySubmit" /><br/>
<br/>
<fup:FileUploadProgress ID="FileUploadProgress1"
OnClientProgressStopped = "function(){alert('Files are uploaded to server');}"
OnClientProgressStarted = "Clear"
ShowUploadedFiles = "true"
OnClientFileRejected = "Rejected"
OnClientFileCleared = "ClearedFiles"
runat = "server"
>
<AllowedFileFormats>
<fup:Format Ext="gif" MaxByteSize="10240"/>
<fup:Format Ext="jpg" MaxByteSize="10240"/>
<fup:Format Ext="jpeg" MaxByteSize="10240"/>
<fup:Format Ext="png" MaxByteSize="10240"/>
</AllowedFileFormats>
</fup:FileUploadProgress>
<asp:Label runat="server" id="uploadedFiles" Text="" />
And here's the code-behind for it:
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
HttpFileCollection files = Page.Request.Files;
uploadedFiles.Text = "";
for (int i = 0; i < files.Count; i++)
{
HttpPostedFile file = files[i];
if (file.FileName.Length > 0)
{
if (uploadedFiles.Text.Length == 0)
uploadedFiles.Text += "<b>Successfully uploaded files: </b><table border=0 cellspacing=0>";
uploadedFiles.Text += "<tr><td class='option2'>" + file.FileName.Substring(file.FileName.LastIndexOf("\\") + 1) + "</td><td style='font:11px Verdana;'> " + file.ContentLength.ToString() + " bytes</td></tr>";
}
}
if (uploadedFiles.Text.Length == 0)
uploadedFiles.Text = "no files";
else
uploadedFiles.Text += "</table>";
}
}
Thanks in advance!!
Looks like it is because you are passing anything to your javascript functions. :
Here is what you have. :
OnClientProgressStarted = "Clear"
ShowUploadedFiles = "true"
OnClientFileRejected = "Rejected"
OnClientFileCleared = "ClearedFiles"
Here is what I think you should probably have. :
OnClientProgressStarted = "Clear();"
ShowUploadedFiles = "true"
OnClientFileRejected = "Rejected();"
OnClientFileCleared = "ClearedFiles();"
Also, several of those functions require parameters, which I did not list above......Hopefully this helps you.

Ajax site performance problem (IE)

I am facing a performance issue related to running ajax in IE (i'm using Ie8), the problem is my website working very slow in ie but it works fine in chrome, and I mean by using SLOW => slow motion . I am using divs and tables and rendering html to div using javascript, besides that I'm using ajax to call 5 different pages (handlers)
function ReceiveServerData(rValue)
{
var x = GetHash();
var feeds = JSON.parse(rValue);
var sb = new StringBuilderEx();
var length = feeds.length;
for(var i=0; i<length-1; i++)
sb.append(News(feeds[i].Id, feeds[i].Title, feeds[i].Des, feeds[i].Icon, i));
if(i == 0)
{
$('#News').html("");
$('#head').html("<i><b><center>لا يوجد اي مقالات حاليا</center></b></i>");
return;
}
$('#News').html(sb.toString());
$('#Pages').html("");
if(feeds[i].count == 1)
{
$('#head').html("");
return;
}
for(var a = 1; a <= feeds[i].count; a++)
{
if('#'+a == x || a == x)
$('#Pages').append("<button id=b" + a + " class='bt2' type='button'><span class='yt-uix-button-content'>"+ a +" </span></button> ");
else
$('#Pages').append("<button id =" + a + " Onclick=javascript:ChangeHash(" + a + ") class='bt' type='button'>"+ a +"</button> ");
$('#head').html("<i><b><center>The page has been loaded.</center></b></i>");
}
scroll(0,0);
}
function News(id, title, des, icon, i)
{
var type = "";
if(i == 0)
type = "&p=big";
return "<table style=width:100%;>" +
"<tr><td rowspan=2 style=width:10%;><img width=70 hieght=70 src="+ icon +">" +
"</td><td align=right style=width:90%;background:url(./Images/BabrBackground.gif)>" +
" <font size=3> "+ title +"</font></td></tr><tr>"+
"<td valign=top align=right> <i><font color=#5C5858>"+ des +"</font></i></td></tr></table>";
}
IE's javascript engine tends to run slower than Chrome, and from the looks of it, your loop is probably making it work harder than its suppose to.
Not knowing anything about your project or what you are trying to accomplish, why do you not just render your html on the server and post that back to the client, instead of having all that javascript build the html for you?
I don't have direct answer to your question. But you can use dynaTrace to pinpoint exact line of code which is causing the issue. For more information - http://ejohn.org/blog/deep-tracing-of-internet-explorer/
I would look at optimising the html generation - have you checked out jTemplates?
I currently use jTemplates to create content from ajax returned JSON data which is inserted into divs on the page - I have no issues with performance despite generating a considerable amount of html content - largely I suspect because jTemplates is highly optimised.

Categories

Resources