In a website I am designing I need to show images which I upload using asp:FileUpload control. So after uploading I am adding div, img and textarea using a string builder and then loading it into panel which I have already created. So is it better to use Stringbuilder to load inner HTML or is it good to use HtmlgenericControls to add the controls like image and textarea. I am using C#. My current coding way is as follows:
Frontend:
<form id="form1" runat="server">
<div class="transbox" id="mainbk" runat="server" style="position:absolute; top:0px; left:0px; width: 100%; height: 100%;" >
<asp:FileUpload runat="server" ID="UploadImages" style="background-color:white; position:absolute; font-family:'Palatino Linotype'; font-size:medium; top: 4px; left: 350px; right: 251px;" Width="500px" AllowMultiple="true"/>
<asp:Button runat="server" ID="uploadedFile" style="position:absolute; font-family:'Palatino Linotype'; font-size:medium; top: 4px; left: 870px; width: 112px; height: 29px;" Text="Upload" OnClick="uploadFile_Click" />
<asp:Panel ID="updtpanel" runat="server" CssClass="transbox" style="width:100%;height:100%;left:0px;top:0px;position:absolute" Visible="false">
</asp:Panel>
</div>
</form>
and backend is as follows:
protected void uploadFile_Click(object sender, EventArgs e)
{
if (UploadImages.HasFiles)
{
int tid = 0;
string fileExt = Path.GetExtension(UploadImages.FileName).ToLower();
if (fileExt == ".jpeg" || fileExt == ".png" || fileExt == ".jpg" || fileExt == ".bmp")
{
HtmlGenericControl d = new HtmlGenericControl("div");
Button btnsave = new Button();
btnsave.Text = "Save";
sb.Append("<div class=" + "\"savback\"" + ">");
sb.Append("<div class=" + "\"head\"" + ">Write Description</div>");
foreach (HttpPostedFile uploadedFile in UploadImages.PostedFiles)
{
id += 1;
tid = tid + 1;
string textid = "txt" + tid;
filepath = Server.MapPath("~/Images/Gallery/" + uploadedFile.FileName);
uploadedFile.SaveAs(filepath);
newpath = "../Images/Gallery/" + uploadedFile.FileName;
try
{
updtpanel.Visible = true;
sb.Append("<div class=" + "\"dataload\"" + ">");
sb.Append("<img class=" + "\"loadimg\"" + "src=" + "\"" + newpath.ToString() + "\"" + " />");
sb.Append("<textarea class=" + "\"txtdes\"" + "id=" + "\"" + textid + "\"" + "></textarea>");
sb.Append("</div>");
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
}
sb.Append("</div>");
d.InnerHtml = sb.ToString();
updtpanel.Controls.Add(d);
updtpanel.Controls.Add(btnsave);
}
else
{
Page.ClientScript.RegisterStartupScript(GetType(), "msgbox", "alert('Please Select only Image Files!!');", true);
}
}
else
{
Page.ClientScript.RegisterStartupScript(GetType(), "msgbox", "alert('Please Select a File First!!');", true);
}
}
Please let me know which will be the good way of creating dynamic controls??
Optimal code:
Doesn't contain more than 50 lines of difficult to read code (agreed, it's not unreadable, but still, minor refactoring would help),
Doesn't mix CSS with HTML, together with presentation-related HTML attributes such as width,
Doesn't use the JavaScript alert.
Let's get back to your question. Which one is better: StringBuilder or HtmlGenericControl?
Better being an extremely vague term, let's answer a bunch of slightly different questions:
Which one is faster ?
Probably StringBuilder, given that it doesn't matter. At all. Compared to the time spent downloading an image (say two seconds, i.e. 2 000 ms.), the comparison in performance between StringBuilder and HtmlGenericControl will be very probably less than a millisecond. Is it important that you waste 1 ms. on a process which takes 2 000 ms.?
Which one is safer ?
How many errors do you spot in the following code?
sb.Append("<div class=\"illustration\"><span-class=\"contents\">")
.Append("<img class=" + "\"loadimg\"" + "srv=" + "\"" + newpath + "\"" + ">")
.Append("/div></span>");
Let's see:
div and span are inverted,
the closing div is missing the '<' character,
img is missing '/' (if the output is XHTML),
there is a typo in src written as srv,
span-class should have been span class,
there is no space before src (srv).
Nearly every of those mistakes could have been easily avoided by letting .NET Framework the task of generating HTML from strongly typed objects.
Which one is more readable ?
IMO, neither. HTML code can be written in a clean way, making it extremely readable. In the same way, it would be easy to be lost in all those calls to embedded controls if the code is a piece of crap.
Which one is more reliable ?
.NET Framework is assumed to be heavily tested and particularly reliable, at least compared to average business applications. The more you confide to .NET Framework, the better, unless you know how to do better and you've tested your approach, submitted it for pair reviews, etc.
In the case of StringBuilder, you can hardly unit-test your code. Letting .NET Framework do the HTML generation in your place means that you can concentrate more on the actual objects you manipulate, and testing them is slightly easier.
So, what is the single best solution ?
Personally, if I were stick with classical ASP.NET (by contrast to ASP.NET MVC), I would create a dedicated control with an HTML template.
If for some reasons, this is not possible, then pick HtmlGenericControl: it abstracts the HTML and let you concentrate on the objects themselves.
If you had a requirement to write clean, readable HTML code, HtmlGenericControl would be a burden, and you would have to pick string concatenation or some templating system. ASP.NET controls are known for generating not-so-good HTML code. Given the HTML code in your question, this limitation doesn't apply to your case.
Related
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
In my existing application file name contains Single quote (') Special character EXample file name: Zahed's.doc. When I am trying to download this file I am not able to download because the file name is contained 's .
Below is my uploading design code:
<asp:FileUpload ID="FileUpload1" runat="server" CssClass="textfield_new1" />
My uploading .cs Code:
bo.Para21 = FileUpload1.FileName.ToString();//ResumePath
string FinalFileName = Convert.ToString(Sno) + bo.Para21;
FileUpload1.PostedFile.SaveAs(Request.ServerVariables["APPL_PHYSICAL_PATH"] + "Resumes/" + FinalFileName);
Below is my Downloading file design code:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:LinkButton ID="lnkbtn_ResumeUpload" runat="server" CssClass="cv_heading" OnClick="lnkbtn_ResumeUpload_Click"></asp:LinkButton>
</ContentTemplate>
</asp:UpdatePanel>
Button click for Dowloading code:
protected void lnkbtn_ResumeUpload_Click(object sender, EventArgs e)
{
string path = lnkbtn_ResumeUpload.Text;
string ResumePath = System.Configuration.ConfigurationManager.AppSettings["ResumePath"].ToString();
System.Web.UI.ScriptManager.RegisterClientScriptBlock(UpdatePanel1, this.GetType(), "SCRIPT", "window.open('"+ResumePath+path + "')", true);
}
My issue is already 800 users are uploaded with the file name 's and I am not able to download that application, how to resolve this type of issue.
Try to encode the filename using HttpUtility.UrlEncode()
https://msdn.microsoft.com/en-us/library/4fkewx0t.aspx
Example:
If your filepath is called "path" you need to encode it first, then send it to javascript.
string filePath = HttpUtility.UrlEncode(path);
System.Web.UI.ScriptManager.RegisterClientScriptBlock(UpdatePanel1, this.GetType(), "SCRIPT", "window.open('"+ filePath + "')", true);
Another solution is HttpUtility.JavaScriptStringEncode which encode your javascript string completely that contains apostrophe.
The problem is that the generated javascript will be broken because it will be:
window.open('...Zahed's.doc');
So the '-character will break your script. Easiest solution is to replace ' with " in your code on the window-open part:
System.Web.UI.ScriptManager.RegisterClientScriptBlock(UpdatePanel1, this.GetType(), "SCRIPT", "window.open(\"" +ResumePath + path + "\")", true);
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.
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.
I am using VSTS 2008 + C# + .Net 2.0. When executing the following statement, there is FormatException thrown from String.Format statement, any ideas what is wrong?
Here is where to get the template.html I am using. I want to format this part m={0} in template.html.
string template = String.Empty;
using (StreamReader textFile = new StreamReader("template.html"))
{
template = textFile.ReadToEnd();
String.Format(template, "video.wmv");
}
http://www.mediafire.com/download.php?u4myvhbmmzg
EDIT 1:
Here is the content for my template.html,
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<!-- saved from url=(0014)about:internet -->
<head>
<title>Silverlight Project Test Page </title>
<style type="text/css">
html, body {
height: 100%;
overflow: auto;
}
body {
padding: 0;
margin: 0;
}
#silverlightControlHost {
height: 100%;
}
</style>
<script type="text/javascript">
function onSilverlightError(sender, args) {
var appSource = "";
if (sender != null && sender != 0) {
appSource = sender.getHost().Source;
}
var errorType = args.ErrorType;
var iErrorCode = args.ErrorCode;
var errMsg = "Unhandled Error in Silverlight 2 Application " + appSource + "\n" ;
errMsg += "Code: "+ iErrorCode + " \n";
errMsg += "Category: " + errorType + " \n";
errMsg += "Message: " + args.ErrorMessage + " \n";
if (errorType == "ParserError")
{
errMsg += "File: " + args.xamlFile + " \n";
errMsg += "Line: " + args.lineNumber + " \n";
errMsg += "Position: " + args.charPosition + " \n";
}
else if (errorType == "RuntimeError")
{
if (args.lineNumber != 0)
{
errMsg += "Line: " + args.lineNumber + " \n";
errMsg += "Position: " + args.charPosition + " \n";
}
errMsg += "MethodName: " + args.methodName + " \n";
}
throw new Error(errMsg);
}
</script>
</head>
<body>
<!-- Runtime errors from Silverlight will be displayed here.
This will contain debugging information and should be removed or hidden when debugging is completed -->
<div id='errorLocation' style="font-size: small;color: Gray;"></div>
<div id="silverlightControlHost">
<object data="data:application/x-silverlight," type="application/x-silverlight-2" width="500" height="240">
<param name="source" value="ClientBin/VideoPlayer.xap"/>
<param name="onerror" value="onSilverlightError" />
<param name="background" value="white" />
<param name="initParams" value="cc=true,markers=true,m={0}" />
<a href="http://go.microsoft.com/fwlink/?LinkID=115261" style="text-decoration: none;">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
</a>
</object>
<iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>
</div>
</body>
</html>
thanks in avdance,
George
At a guess, the html contains javascript or another source of braces ({ and }) which would all need doubling (to {{ and }}) to be usable with string.Format. I expect a different (more obvious) token may be in order, i.e. %%FILENAME%%. Then use either regex or string.Replace.
If you have a single tag, string.Replace is fine; if you have lots, there are tricks with regex and MatchEvaluator that may be helpful - like so but with a different regex pattern.
Update after the example html added: I would definitely use a different token; at the most basic level:
<param name="initParams" value="cc=true,markers=true,m=%%FILENAME%%" />
and
template = template.Replace("%%FILENAME%%", "video.wmv");
Your template contains { and } characters which need to be escaped, otherwise they confuse String.Format. Escape them using {{ and }}. Alternatively, use a different mechanism such as String.Replace.
string.Format() does not handle { and } in the format string. You need to replace { with {{ and } with }} everywhere in your template.html file. Except for the single place where you use the {0} placeholder.
Not very elegant.
Instead, consider using a template engine. See http://csharp-source.net/open-source/template-engines for some suggestions.
The next-best solution is to use regexes (with MatchEvaluator) or string.Replace(), as suggested by other answers.
Edit:
Here's an example using the StringTemplate template engine:
StringTemplate htmlpage = new StringTemplate(File.ReadAllText("template.html"));
htmlpage.SetAttribute("content", "video.wmv");
Console.WriteLine(htmlpage.ToString());
Change a single line in your template.html file:
from:
<param name="initParams" value="cc=true,markers=true,m={0}" />
to:
<param name="initParams" value="cc=true,markers=true,m=$content$" />
When the template engine encounters $content$ in the template, it replaces it with the value of the 'content' attribute that you set using code.
Using StringTemplate, you can do simple looping and conditionals within your template. See the documentation.
Wat are the contents of the 'template' variable ?
Difficult to say what 's wrong with your code, but presumably, the template variable does not contain a string which as a place-holder.
(Like "this is some string {0}").
I think that you should make use of the tools your IDE provides: debug the code, use watches to inspect the contents of the template variable.
Whats in the template file?
if there are curly brackets that are not of the format {int} or there are more than there are arguments for the format statement, it'll throw an exception.
What is the message in the exception?
It's your Css thats doing it. As somoene else mentioned you'll need to doa regex replace, or a bunch of String.Replace commands in a row mark you variables with %%VARIABLE_NAME%% and use string replacement to replace them