I am using ASP.NET 4.0 WebForms. I am also using master pages which inherit from other master pages. I have controls inside panels. Basically there are multilevel containers. This is causing elements to have HUGE ID's. I am seeing ID's about 300 bytes long!
When there are hundreds of elements in a page, these ID's increase the page's size dramatically. I have a GridView with binding controls.
What is the best way to have each server control have the shortest ID possible? Is there a way to have each element not be dependent on its container (other than ClientIDMode="static") ID even if but still be unique in the page? Last, does ASP.NET MVC alleviate this issue?
I would suggest changing the ClientIdMode to either Predictable or Static in order to see if that produces shorter ID's.
Further to that this CodeProject article appears to achieve what you need.
MVC absolutely alleviate this issue because there is no server side rendering of html code in the same manner. All of your html is directly in your views so you have full control over every item. You also run the risk (in the case of a page that has hundreds of inputs) of colliding inputs.
One way you can help shorten all the html produced in WebForms is to remove anything that is not absolutely necessary to be a webusercontrol. For instance, most labels are static. They can replaced normally with standard text or items that don't include the runat="server" attribute. This will prevent ids from being generated in the first place. Another way to reduce the amount of junk that gets generated is to remove as many controls as you can from the ViewState. This will prevent them from loading their state data and keep the ViewState shorter.
ClientIDMode is an inheritable property so you can set it in the web.config (global), web.config (local) or page level. You could also use it individually. Your question specifically eliminates this, but it would probably be the best option with the most flexibility without rewriting what you already have. If rewriting is not an issue, I'd recommend using MVC.
I think ClientIDMode=static is in one of the way. YOu can set this in your web.conf also. And in Asp.Net mvc, you have the full conrol over html (especially in Razor). There is no such thinks like webforms. You have control over assigning ids to html tags. Infact Asp.Net mvc is answer to all other frameworks.
Last, does ASP.NET MVC alleviate this issue?
Yes.
There is no ViewState in MVC and you are not running any controls on the server.
You are not using any server controls which generate tons of hard to read HTML.
You have complete control over ClientID's in MVC.
Click
The above markup will always have the id of myID unless I change it myself.
Related
Hello I am trying to lear how to create Dynamic User Controls in asp.net.
I just know that this type of controls are created or loaded at run time.
Someone knows a good tutorial about this topic?
thanks in advance,
The best thing you can learn about dynamic controls in ASP.Net webforms is how to avoid them. Dynamic controls in asp.net are filled with pitfalls. I almost always recommend one of the following alternatives:
Place a reasonable fixed number of controls on the page, and then only show the ones you need.
Figure out the source for the dynamic controls and abstract it out to a datasource (array, ienumerable, list, etc) that you can bind to a repeater, even if it's just a call to Enumerable.Range().
Build a user control that outputs the html you want, bypassing the entire "controls" metaphor for this content.
If you really must work with dynamic controls, it's important to keep the stateless nature of http in mind, along with the asp.net page life cycle. Each adds it's own wrinkle to making dynamic controls work: the former that you need to create or recreate the controls every time you do a postback, and the latter that you need to do this before hitting the page load event - usually in page init or pre-init.
Typically what people are talking about here is the dynamic instantiation and addition of a control to a placeholder.
For example
Control ControlInstance = LoadControl("MyControl.ascx");
myPlaceholder.Controls.Add(ControlInstance);
The above instantiates MyControl.ascx and places it inside of a placeholder with id of myPlaceholder.
I agree with #Joel by knowing the page lifecycle, the stateless nature in mind etc it is possible to avoid the pitfalls. The main things to watch out for, which I have had to do, are:
Page_Init – initialise the controls that are on the page here as they were the last time you rendered the page. This is important as ViewState runs after Init and requires the same controls initalised the same way as the way they were previously rendered. You can load the control using the code from #Mitchel i.e.
Control ControlInstance = LoadControl("MyControl.ascx");
myPlaceholder.Controls.Add(ControlInstance);
Page_Load – Load the content of the controls in here as you would with any control that isn’t dynamically loaded. If you have kept a reference to them in your page_init they will therefore be available here.
Keeping to this structure I haven’t had too much difficulty as this is appears to be the way that ASP.NET was designed to work, even if all the samples on MSDN don’t do it this way. The biggest thing that you then have to watch is tracking what state the page was in in regard to the controls that you have had rendered.
In my case it was take the section number of the multipage survey and reload the questions from the database, so all I had to do was track the currently rendered section number which wasn’t difficult.
Having said all that if you are using dynamic controls just to show and hide different views of the same screen then I suggest you don’t use them. In this case I would much rather use either user controls (with the inappropriate ones hidden), placeholders to mark areas that aren’t to be rendered yet, or separate pages/views etc. as that way you keep the pages to a single responsibility which makes it easier to debug and/or get useful information from the user about which page they were on.
The Microsoft article is very good, but the best article that I have been read is in the bellow link:
https://web.archive.org/web/20210330142645/http://www.4guysfromrolla.com/articles/092904-1.aspx
If you are really interested in ASP.NET Web Forms dynamic controls, I recommend that you study the DotNetNuke CMS Portal. DotNetNuke is one of the best cases using dynamic controls as your core feature to build dynamic portals and pages using ASP.NET Portals. It is free for download in www.dotnetnuke.com.
I hope it helps
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.
In terms of performance. Is it a good idea to build your own data grid (assuming you have the time) having in mind that you will create one that match perfectly your need? Getting rid of many unnecessary properties and methods. The rendered page might be smaller making the download faster?
thanks
The properties and methods of a server control have no direct relationship with the size of the rendered HTML. Simply removing methods won't make the slightest difference in the size of your download. In my experience, the .NET controls work well enough. If you encounter a performance problem, you can always drop in a different implementation later.
As ASP.NET already includes the Repeater control and the DataList control, both of which allow you to specify the HTML output of the control, there is little need to create a new control for performance reasons.
I generally prefer to add controls dynamically, like table and generic html controls, to the ASPX page, rather than add them in the ASPX page and set the properties dynamically.
Which approach is considered "better practice"?
Also is using generic html controls dynamically a better practice than outputting formatted html strings to an asp:literal?
Keep them in the .aspx
Adding them dynamically leads to view state issues and they must be added in each post pack. I ran into this when building a user generated forms app. I Broke down and used the controls visibility property as a work around. That said if your eliminating view state and post back from your app these may not be issues for you.
https://web.archive.org/web/20211031102347/https://aspnet.4guysfromrolla.com/articles/092904-1.aspx
Since in both approaches you end up with a set of code that adds controls and assigns values to their properties then the best practice is the approach that is the most readable.
Due to complex decision logic it may be better to do it all yourself on the hand for fairly static control layout where only the properties need modifying placing the control in the ASPX would be more straight-forward.
.Net is kindly changing the element ids on my pages by appending a ct100_ to them. As much as I appreciate microsoft trying to help me keep from duplicating ids on my site, I think I can manage it on my own. Can anyone tell me how to prevent this?
Thanks in advance.
That's just how aspnet works. Controls provide the clientid method for you to use in your code behind for this reason.
If you want to refer to objects from js, you can either inject the clientid or use classes or other attributes.
Edit: Note that this only applies to the ASP.NET controls. If you use the HTML controls, the given IDs are preserved. You can access them in your code behind by adding the runat=server attribute to them, too. Obviously these controls break the webforms model with viewstate, etc. but they do give you your desired functionality.
Of course it's been a while since I worried about it so I could be wrong...(please comment or edit if I am!).
You cannot prevent this in the current version of ASP.NET - the next version will allow you to do this. Perhaps ASP.NET MVC is a good choice for you?
Any control which has the INamingContainer interface on it will get the control heirarchy appended to it to allow for multiple controls to be on the page without conflicting. You should be using the ClientID property of the control if you wish to know what the id of the element will be on the client.
You will need to:
override regular controls' behavior to decouple the Control.UniqueID property from the Control.ID property
override naming container controls to allow us to control how ID generation is done and how to find a control
References:
http://nunogomes.net/post/2008/06/02/ASPNET-Controls-Improving-automatic-ID-generation-Architectural-Changes-(-Part-3).aspx
http://weblogs.asp.net/nunogomes/archive/2008/06/04/asp-net-controls-improving-automatic-id-generation-architectural-changes-part-3.aspx
http://forums.asp.net/t/1394822.aspx
to not use anything on the server side.
This is an inherent aspect of the ASP.NET system, and there is no way to use .NET Server controls and not have the prefixes appended.
To access the client-side name, you can use the myControl.ClientID property.