Is it bad to use runat="server" on <tr>? - asp.net

I'm supporting an application that uses runat="server" all over the place to show/hide table rows.
For example, in places where there are dependent DropDownLists, the row with the child ddl will be hidden until a value us chosen in the parent ddl.
Is that a bad practice? Is there a better way to do this?

I use runat="server" anytime I need it. So I think you can use it too. :-)

I think that's absolutely terrible practice. First of all you do not need to make the trip to the server to hide and show controls, unless you need new data.
Second, any decent javascript framework will allow you to hide show controls based on the control's id, class name, or whatever css selector. Moreover using a javascript post/get to a generic handler will give you the data that you need without the postback.
I'd suggest using JQuery, or some other alternative.

It depends on how much you care about performance. Anything that is marked with runat="server" goes through more processing than just client side tags.
Personally, I've used them before. Especially in the situation where a table cell or table row is relying on data from the server. You can use Javascript or JQuery with a hidden field but you still have to hit the server for the hidden field, so it doesn't buy much.

It's not bad to use runat="server" with standard HTML controls. Often you'll find the use of PlaceHolders to show and hide content on pages, or in ASP.NET MVC you might see the use of inline code blocks such as <% ... %> within the views. On it's own and not in consideration of other design aspects, it's neither good nor bad.

That's what I do to hide the row containing other server controls. The other options are to use a asp:panel or other container, but that will add more HTML without any gain.

I don't think it's necessarily bad practice. I've done the very same thing plenty of times. I think it's mainly personal preference.

Not at all. ASP.NET supports making any html tag run on the server side. Your alternative is to wrap the tag in a Panel, and hide or show that. If you're not looking for the extra functionality or want to control the output yourself, making an html tag run on the server isn't a problem.

Related

ASP.NET - improve performance

Is there any reason use standart HTML controls (input type=text,input type=checkbox) instead of asp.net controls ( asp:TextBox, asp:CheckBox) to improve performance?
IMHO this would be a micro optimization. You will gain performance but it won't be noticeable. On the other hand you will loose much of the flexibility offered by the server controls.
You could try to reduce the size of the ViewState by disabling it for controls that don't need it. This will reduce the size of the generated pages and improve performance.
The ASP.NET user controls will all have ViewState associated with them unless you explicitly set
EnableViewState="False"
As such, you will bloat the size of the underlying page if you have a large number of controls. As a general rule, use what meets your needs and nothing more.
Do you need to access the user control in the code-behind?
Do you need the control to maintain value across post-backs etc?
In most cases, it won't make a difference, but it is good to keep your page clean if you don't need these features.
As always with performance optimizations: it depends on the situation. Test it in your project and see if it makes any difference.
Also with .net 4.0 another con of using server controls is gone, since you can set ClientIDMode to Static, which will give you full control over ID's on your controls. Previously using just a standard textbox or button (without viewstate) would still render crazy non-readable ID's because of the way Naming Containers work. Those days are over now though :)
Remember your three options are:
use regular html which can't be referenced on the server.
add runat="server" to your existing html-tags (ie. ) and you'll be able to access it as an HtmlControl.
use the asp.net tags (<asp:* runat="server" />)
The disadvantage of option 3 is that you don't always know what the rendered html-markup will be and you have less control over it. I personally only use option 3 for more advanced controls like , the button () and third party controls. For normal html-markup that I need to reference on the server I prefer option 2.
Regarding performance I would mainly look at the rendered output, how much extra bloat is rendered to the client and such. CPU-time on the server using one or the other approach I would say is secondary compared to the different caching techniques ASP.Net has already.

Alternatives to ASCX User Control without a server-side form?

I've got an ASP.NET 3.5 Web Forms application in which a large chunk of code needs to be duplicated between a few different pages. Sounds like the ideal candidate for a user-control right? Problem is, this cannot be contained within a <form runat="server"> because it contains a client-side form of it's own.
There are no runat=server controls or postbacks or anything that really need that webform - think of it just as a chunk of HTML with a few basic <% %> tags. I'd just want to set a property on the control when it's loaded, so that it knows what to output. This is purely an exercise to make the code easier to maintain.
Before I resort to using an oldskool <!--#include-->, is there some better way of doing this?
You can still use a normal user control. Just don't rely on viewstate and postbacks and you shouldn't have any problems.
<%=Response.Write(File.ReadAllText(Server.MapPath("~/includes/filename.ext")))%>
Something along those lines, anyway.
Edit: Same functionality as a server side include, but if I'm not mistaken, enabling the SSI syntax requires an IIS change, where as this wouldn't.
Edit 2: I didn't see the note that your include contains asp.net code. This would obviously only work for client side code only. My mistake.
You can have as many form controls as you want but only one can have runat="server".
Some other techniques:
http://webproject.scottgu.com/CSharp/UserControls/UserControls.aspx
http://weblogs.asp.net/scottgu/archive/2005/08/28/423888.aspx
I'd still make it a control. The <% %> stuff could be labels/literals for more flexibility, and as soon as you get done saying there are no postbacks needed, you'll need them. Best to set up the other pages to include it as a control now for easier changes later. Heck - you could even take advantage control-level caching!

WebControl vs HtmlControl. Cos and pros using them in web forms application

In web forms application, for server code, when use WebControls and when use HtmlControls? For example if I want write some text inside of span tag, should I use:
<span id="someid" runat="server"></span>
or
<asp:Label id="someid" runat="server"></asp:Label>
The main difference is that HtmlControls only provide a way of addressing a part of the page during the page cycle, whereas WebControls are stateful.
In your example, if you assign some value to the Label text, it will keep it across PostBacks.
In my experience is far better to use HtmlControls if you can, they are much more lightweight and they don't fill up your ViewState. Do use WebControls when you need them to be stateful.
For example, you might want to use a Label for a page title, because you can only assign the value once (typically in Page_OnLoad inside a if (!IsPostBack) block). You might want to use an HTML span to provide some status feedback (where the status is updated at each postback, for example).
I would use the span approach. Whatever server control you use it will finally render as an html control.
If your functionality can be done using an html control better use that..
For a server control like data grid you might have to code more to achieve those functionality by using an html table.
In that case you can use a server control.
one behaviour of asp:button is it always render as input type=submit
and asp:imagebutton always render as input type=image

ASP.NET: Bind Repeater using jQuery?

I have a Repeater control that I bind server-side. It repeats a series of divs, and does so with no problem. I have some buttons that I use to sort the repeater (newest, highest ranked, random) and this works the way it should.
I would like to improve my user experience by making the buttons sort the divs using Ajax/jQuery somehow so that there is no page postback and the user does not lose his/her spot on the page.
Is there a way to use jQuery to access server-side code like this, or use Ajax to re-bind a server-side control?
Thanks... if I need to list more details, please let me know!
EDIT I'm aware of UpdatePanels, but I would prefer not to use them if I don't have to.
Have you considered moving the Repeater's functionality to the client-side?
Doing it that way, functionality like paging and sorting is not very difficult to add. In fact, you can lean on the framework pretty heavily by using ADO.NET data services as the service layer.
It's relatively easy.
Move your repeater to a separate custom control, let's say MyControl. Now repeater in your page becomes uc1:MyControl.
Wrap MyControl into a div:
<div id="mydiv">
<uc1:MyControl ID="MyControl1" runat="server" />
</div>
Create a new page, pgMyControl.aspx, that contains MyControl only.
On your main page, add jQuery handlers to your sort links. Use load method to dynamically replace div contents:
$('#link_sort_random').click(function()
{
$("#mydiv").load("pgMyControl.aspx&sort=random");
}
Use QueryStringParameter in datasource inside MyControl to change order. Or use Request.QueryString in code-behind file.
Using an updatePanel or a jquery Ajax postback are the same thing essentially. Both will ask your code to fetch the new query, then make your control render itself, and then feed the HTML back to the client as a partial page render, and then insert the content in place of the old content in the same DOM location.
It is considerably harder to make JQuery and ASP.NET talk to each other this way due to the nature of web controls and their lifecycle that determines when they render. An updatePanel knows how to call all this, maintain proper viewstate and return the result to the correct location.
In this case, don't make things any harder on yourself, use the updatePanel unless you have some very specific reason not to.
EDIT: If you're having JQuery issues with update panels it is probably due to the fact that new DOM nodes being created. JQuery has the live event to handle this. It will notice when new DOM elements are created and match them against your selector even after the document ready.
Maybe it's an OT, but you can consider to change the way you bind even the client and the server control, using XSLT transformation instead od the classics server controls.
You can find an example here (sorry, it's in italian...).

How can I minimize the weight of my ASP.NET pages?

I rely heavily on nested Master Pages in my web portal, this causes ASP.NET to generate huge ID tags for controls it creates, for example:
"ctl00_ctl00_MainBody_ctl00_lblDescription"
for a lblDescription Label i've created.
Is there any way to reduce this clutter?
Any other techniques(sorry for being general) to reduce page weight other than removing the viewstate?
Look at Yslow and do what it tells you (I would start here)
Turn off viewstate
Use jsmin to reduce the size of your JavaScript files
Reduce the size of your CSS (dead link)
Compress your response with standard gzip/deflate compression
Using ASP.NET MVC will give you smaller IDs
Whenever possible use HTML Controls. HTML Controls. They are lighter since don't have server-side objects unless you specify the runat="server" attribute.
I don't know how to remove the client id bloat but some general tips for making your pages smaller would be:
Minify and combine any .js/ .css into one file.
include css at the top of the page and js at the bottom (not really going to make it smaller but UI will load faster)
Enable IIS static/dynamic compression
Use caching for controls and pages
Ajax content loading - it's helps when you want to see main content faster than content with less priority
Terrapin has some great suggestions, but they are pretty idealistic. If you are looking for more applicable solutions to your current situation, check out control adapters.
The CSS Friendly adapters will do a lot of work for you to convert your ASP.NET controls from large ugly, long id named tables into more concise divs, with shorter names.
I have used them in a past and they can really make a huge difference. Other than that, turn the viewstate off on any control that doesn't need it. Conform to proper CSS/HTML and it will make another significant difference.
Best of luck!
To minimize the weight of your ASP.NET pages, you can also override the PageStatePersister property (of the Page class) with SessionPageStatePersister. See example here. That way, the Viewstate will be kept in the Session object on the server side, thus reducing the size of the html page on the client side.
Especially inside repeaters, ListViews and GridViews, name your controls something short.
This should be obvious by the Context (A list of Products)
If you have only one HyperLink inside a repeater, call it hl. You don't need to call these controls HyperLinkProduct.
<asp:Repeater id="rptProducts" runat="server">
<ItemTemplate>
<asp:HyperLink id="hl" runat="server" NavigateUrl='<%# Eval("URL") %>'>
<%# Eval("Name") %>
</asp:HyperLink>
<asp:Image id="img" runat="server" ImageUrl='<%# Eval("ImageUrl") %>' />
</ItemTemplate>
</asp:Repeater>
This will render something like:
<a id="ctl00_rptProducts_ctrl0_hl" href="/products.aspx?id=5">
Product Name
</a>
<img id="ctl00_rptProducts_ctrl0_img" src="images/5.png"/>
Multiply those ID names by a 100, and your IDs start to take up a lot more space if you use long descriptive names. Inside Repeaters, short IDs should be clear enough, if your Repeater is well-named.
Using CSS Sprites can speed up your page by reducing the number of requests. Here are a few articles I found.
In your case of using a label, make sure that you really need to use the label (which generates the text in a <span> tag. You could use a Literal instead.
Set EnableViewState="False" on controls that don't need it (or on the entire page/website)
If you're trying change the obscure ids generated by ASP.NET, there's not much you can do there.
Use html/css to style your pages, avoid tables for layout, when creating a label specify the id, shorter it is, the better.
Turning off the viewstate, as you mention, is good. Also I have noticed that the ASP.NET tree control generates a very large amount of HTML (if you have a fair number of nodes). I ended up writing my own tree control that generates 1/4 the HTML of the standard tree control. So you could look for controls like that, that are especially bad, and write your own control.
I guess if you were desperate to do this without retooling your pages (and none of the other sensible ideas worked ;) ), you could do this:
Write an http module that parses and extracts the ids with shorter, recognizable unique ids on the fly as the page is sent to the client, and store them in an application scope hash table. Then, on the return trip perform the reverse step for the incoming data.
At least, that's what I'd try. I'm not sure how nicely it would play with certain html and/or javascript constructs, but I think it could be done.
I suspect it would be a pain in the butt to do, especially if the shorter unique ids happened to conflict with any legitmate non-id values.
EDIT: Just remembered. You'd need to handle the ViewState too... (that would need to be decoded, fixed and re-encoded. Seems like a lot of trouble :) But then again, if you're going to go to that trouble, you can compress the viewstate a lot better by overriding the load/save viewstate methods...
I cut some huge pages (200K of html) down to about 30K using that method a couple of years back. In fact, using custom compression on the ViewState can often be enough to reduce a page size hugely.

Resources