What are the naming guidelines for ASP.NET controls? - asp.net

We are in the process of nutting out the design guidelines we would like to use in our development team and got into a discussion today around how ASP.NET controls should be named. I am talking about our good friends Label, TextBox, Button etc.
We came up with the following three possibilities that we voted on: (Example is a TextBox to enter/display a FirstName)
Add the control type as a postfix to your controls ID: [FirstName_TextBox] or [FirstName_tbx]
Add the control type as a prefix to your controls ID [tbxFirstName]
Set the ID of the control to FirstName and name related fields (like a label for the textbox or a validator) as in option 2 [lblTextBox].
We ended up deciding to use option 2. It's not as verbose as option 1 and I like that it specifies what control it is before the name of the control.
My question is whether Microsoft has released any guidelines for these prefixes and or if you have any comments about our decision.

The reason Visual Studio adds "TextBox1" when you add it to the page is because Microsoft has no way of knowing how you intend to use it. Naming it "Control1" would be too confusing because it could be any number of controls.
Microsoft provides guidance in general for OO naming conventions, but not specifically for naming UI controls. Since UI controls are ultimately variables used in code, they should follow the same convention as any other variable - no hungarian notation prefix.
msdn.microsoft.com/en-us/library/xzf533w0(vs.71)
msdn.microsoft.com/en-us/library/ms229002(VS.80)
The main reasons are...
Type of control may change from textbox to listbox, then all associated code will have to be fixed (noted earlier)
Your code should be more concerned with the content of the control and less with what type of control it is. When you are concerned with the type of the control, you start to depend on certain functionalities and you break encapsulation - you should be able to easily swap controls without changing much or any code. (Basic OOP principle)
It is fairly easy to come up with prefixes for the standard controls, but new controls are being developed every day. You may make your own WebUserControl, or you may purchase a set of third party controls. How will you decide which prefix to use for the custom controls? Instead of focusing on the type of control, your code should be concerned with what information is contained in it.
Examples
txtFirstName => firstName or FirstName
txtState => state or State
cboState => state or State (prime example of changing control types what about lstState or rdoState - they should all have the same name because your code is not concerned about the type of control,rather the state the user selected)
ctlBilling => billingAddress or BillingAddress (custom control - with hungarian notation it is not very evident what the control even is, but with a meaningful name I begin to understand the information contained in it. i.e. billingAddress.Street, billingAddress.FullAddress etc.)

Not sure about Microsoft official standards, but this is what i've done through out my development career.
I generally abbreviate the control type in front of the the name of what the control does.
I keep the abbreviation lower case and the control's name CamelCase.
E.g. A texbox for username becomes tbUserName
Here is a list of standard abbreviations I use:
Abbr - Control
btn - Button
cb - CheckBox
cbl - CheckBoxList
dd - DropDownList
gv - GridView
hl - Hyperlink
img - Image
ib - ImageButton
lbl - Label
lbtn - LinkButton
lb - ListBox
lit - Literal
pnl - Panel
ph - PlaceHolder
rb - RadioButton
rbl - RadioButtonList
txt - Textbox

I find that most of the time I care about what kind of information the control is for rather than what control type is currently being used to capture that data, so I prefer the type of information before the control type, so I can find it in a sorted list in the IDE:
AgeRangeDropDownList
AgreedToTermsCheckBox
FirstNameTextBox
LastNameTextBox
VS:
chkAgreedToTerms
ddlAgeRange
txtFirstName
txtLastName

I'm not sure of the guidelines regarding ASP.NET, but in the book Framework Design Guidelines from Microsoft, there are several best-practice guidelines about naming of class members. Since ASP.NET Controls in most cases result in a protected field of the appropriate type, I consider these naming guidelines to apply for ASP.NET controls as well. In fact Code Analysis does not differentiate on Control reference fields and other fields.
These guidelines recommend using a naming scheme that implies the logical use rather than a type-descriptive variant. There are several reasons for this. The prefix is implies a type to the developer that might not be correct due to later changes. It adds an extra step in code maintainence. If you change your Button control into a LinkButton control the name also needs to be changed to correct the prefix.
For that reason I would call the control FirstNameEdit etc...

Microsoft does provide some guidance here.
When you drag a control onto a web form you get something like "TextBox1" automatically. That's the IDE telling you that you should change the "1" part for your specific needs.
In that case, "TextBoxFirstName" seems like the way to go.

Two reasons why I prefer option 1:
FirstNameTextBox more closely matches my business object.
More usable with IntelliSense.
Having said that I am considering changing to FirstNameCtrl for the reason csgero pointed out about changing control types. So why bother with any postfix or prefix, to reduce/remove the posibility of conflicts with asp/win form properties.

I think it is better to use option 1 because it is easy to find the field by its meaning and its usage to understand programming coding down the road . Also,it is more usable with IntelliSense to find where we use this field for in our programming code. Therefore I can find the right control by the name of the meaningful field. I will not remmember what kind of control I use for this field but I can find this field by using the meaningful of field name instead of the type of control example I want to find "City" control , I just typ "City" , Intellisence will show me all information for this control but if I do not remember what kind of control I use for , I do not know what to begin....

Abbreviation || ASP.NET Control
STANDARD CONTROLS:
btn Button
cb CheckBox
cbl CheckBoxList
ddl DropDownList
fu FileUpload
hdn HiddenField
lnk Hyperlink
img Image
ibtn(btn) ImageButton
lbl Label
lbtn(btn) LinkButton
lb ListBox
lit Literal
mv MultiView
pnl Panel
ph PlaceHolder
rb RadioButton
rbl RadioButtonList
tbl Table
txt TextBox
v View
DATA CONTROLS
dtl DataList
dp DataPager
dtv DetailsView
ets EntityDataSource
fv FormView
gv GridView
lds LinqDataSource
lv - ListView
ods ObjectDataSource
qe QueryExtender
rpt Repeater
smd SiteMapDataSource
sds SqlDataSource
xds XmlDataSource
VALIDATION CONTROLS
cpv CompareValidator
ctv CustomValidator
rv RangeValidator
rev RegularExpressionValidator
rfv RequiredFieldValidator
vs ValidationSummary
VALIDATION CONTROLS:
cpv // CompareValidator
ctv CustomValidator
rv RangeValidator
rev RegularExpressionValidator
rfv RequiredFieldValidator

We also use number 2, however I'm not totally convinced it is a good approach. It is Hungarian notation from the "bad" kind, meaning that the prefixes signal the type (syntax) and not the purpose (semantics). The problem with this is that what starts as a TextBox might later become a DropDown and then a RadioButtonGroup, and you'll have to rename the control each time.

Almost everyone uses Hungarian-style prefixes (option 2).
Semantic naming is less useful because "Firstname" is actually the texbox.Text value, not the textbox itself.

I tend to go with the control type as a prefix and the name of the control afterwards but I always CamelCase so in your example for different types of controls you might have..
TxbFirstName
DdFirstName
ChbFirstName
For intellisense reasons I also always fully qualify the name of the control so I wouldn't do any of the following...
TxbFName
TxbClientNo
TxbNoOfCpn
But ultimately down to personal preference

I've been struggling with this problem too. I used to use the "hungarian style prefix".
Now I take a different approach, I try to see the controls as private fields from my class. I don't pre- of postfix my private fields with their type, so why should I do that to an TextBox?
So what used to be:
var newCustomer = new Customer();
newCustomer.Name = txtName.Value;
newCustomer.Address = txtAddress.Value;
newCustomer.City = txtCity.Value;
newCustomer.HasEnoughMoney = cbHasMoney.Selected;
Becomes:
var newCustomer = new Customer();
newCustomer.Name = name.Value;
newCustomer.Address = address.Value;
newCustomer.City = city.Value;
newCustomer.HasEnoughMoney = hasMoney.Selected;
To be honest, I couldn't care less if the "name" control is a text box or what else, I just want it's value.
And if it's not clear enough if your talking about your control or about another field/variable, I think you should either reconsider the name of that field/variable or the function of you class (meaning it might be a little bit to big?).

If you look at it from a code maintainance point of view what would be the best notation to look at after you did the code 2 years ago. Although we try to ensure that forms don't have too many fields on them we all know that this sometimes happens. If we used the Hungarian type notation by prepending the control type I think it would be easier to see where that value is coming from instead of having to figure it out in the event the variable name doesn't make it obvious. If you are using any type of Refactoring tool then changing the name of the control would change the code automatically thereby reducing the change control arguement.

I don’t think there’s a right or wrong answer here, whatever you decide, I think the most important aspect is just to be consistent when it actually comes to coding.

I use uxCity so that you know it's definitely the User Interface control and not some other object but you don't need to change it if you go from a TextBox to a DropDownList.
However If I had a DropdownList and a Textbox, I'd need to use dlCity and txtCity
Or I'd use a combo cboCity.
Hungarian notation was de rigeur when you were limited to 8-character names and no intellisense or debug highlighting. It was a discipline and you could see that if the coding style was correct, the code was likely to be correct. It was used on variables too so you could read the code and understand it as it was a DIY type enforcement.
However, I do use CityTextbox, CityTextboxLabel
CityUx, CityUxLbl
It all depends on who is setting the standards on the project.

I found the only reason to use Hungarian notation was that the IDE did not have intellisense and it was not easy to figure out what was what so iCounter was an integer
However the time of using brief to develop is long gone and the IDE shows you the info in a second
Then you inherit VB.NET code and it is not case sensitive so what do you do?
lblFirstName, txtFirstName
One is a label the other is the textbox
So how do you name these without case sensitivity and actually know what they are?
uxFirstName & uxFirstName does not work
the only answer i have found is to use Hungarian notation, yes i threw up in my mouth. Then again its vb.net and it should be case sensitive since .net is and all of the compiles to IL.

Not really sure about any guidelines, i suspect there are, but I always use number 2 as well!

these are really just based on your preferences but yes, option 2 as described is less verbose and indicates to you the type of control even before its name is shown.

Related

detailsview, how null value came?

I am having a problem dealing with Detailsview InsertItemTemplate. I am following ASP.Net 4 for Beginners by WROX.
I have a dbase with table Employee(EmpId, Name, DoB, Sex, DeptId, Position)
I am trying to insert values into this table using Detailsview.
Using the regular detailsview I could insert all the values. It works fine.But when I converted the detailsview to template, there is a problem.
What I did?
-On Smart tag of Detailsview, I clicked Edit Fields. Delete all the avaible fields except EmpID and added Template Field from Available Fields.
-Again on Smart Tag of Detailsview, clicked Edit Template and selected InsertItemTemplate in DropDownList.
-Using Standard components from Toolbox, I added text box for Name and dropdownlist for other fields. (I have not deleted EmpId, so I do not need one for it).
-Here is the rest of Markup view:
Enter following information to register:
Name:
DoB:
Sex:
DeptId:
Position:
-And here is the code behind CS file for Insert event for detailsview
protected void DetailsView1_ItemInserting1(object sender, DetailsViewInsertEventArgs e)
{
string id = System.Guid.NewGuid().ToString();
TextBox txt_name = (TextBox)DetailsView1.FindControl("EmpId");
e.Values["EmpId"] = id;
DropDownList ddl_month = (DropDownList)DetailsView1.FindControl("DDL_Month");
string month = ddl_month.SelectedValue;
e.Values["DDL_Month"] = month;
DropDownList ddl_day = (DropDownList)DetailsView1.FindControl("DDL_Day");
string day = ddl_day.SelectedValue;
e.Values["DDL_Day"] = day;
DropDownList ddl_year = (DropDownList)DetailsView1.FindControl("DDL_Year");
string year = ddl_year.SelectedValue;
e.Values["DDL_Year"] = year;
DropDownList ddl_sex = (DropDownList)DetailsView1.FindControl("DDL_Sex");
string sex = ddl_sex.SelectedValue;
e.Values["DDL_Sex"] = sex;
DropDownList ddl_pos = (DropDownList)DetailsView1.FindControl("DDL_Pos");
string pos = ddl_pos.SelectedValue;
e.Values["DDL_Pos"] = pos;
DropDownList ddl_deptid = (DropDownList)DetailsView1.FindControl("DDL_DeptId");
string deptid = ddl_deptid.SelectedValue;
e.Values["DDL_DeptId"] = deptid;
}
-Could you also suggest me how to combine the three selected value from dropdownlist for Date of Birth and add it to database.
Thank you!!!
To elaborate:
Yes that would be the first step. The connection string should be added to your web.config under the '' element:
http://msdn.microsoft.com/en-us/library/bf7sd233.aspx
You can then read this out in your code:
Read connection string from web.config
The following shows a reasonably good general form for doing a database update into a SQL database based on values you're taking from a form - done in C# (which I'd recommend getting started with instead of VB.NET, for various good reasons)
Update database with values from textbox
This shows how to add the connection string directly inside the code instead of from the web.config, which may be simpler for you in the first instance. This shows how to do the database update by using 'parameters' in the query (the 'variables' if you like that are denoted with # symbols). Using parameters is basic good practise that it's worth getting used to (don't worry too much about why, but you may want to research the 'SQL injection' technique that hackers use to attack websites). This is a good starting point for you. It may seem complex at first, but ask any developer with a few years of experience and they'll tell you it's generally the way to go. As you progress in development the tempting 'out of the box' stuff provided by .NET becomes increasingly limiting, and you lose the ability to finely tune performance and other characteristics of good applications.
The example I've given is actually still relative simple. As you develop, there are other aspects you should start bringing into your code, especially creating methods that do the bit that accesses the database (by using a SQL query) in a separate class that gets called a 'Data Access Layer' (often an intermediate layer gets used called the 'Business Logic Layer' or similar, but don't worry about that yet).
Also the example I've given should really be packaging up some of the code in methods that give a clear indication of what the code is doing e.g. at a simpler level a method 'UpdateMachineDetails' could at least be used to encapsulate the code that updates the database.
There are lots of tutorials if you Google for it that show you how to update a datbase 'manually' in .NET, but the form I'm giving you puts you on a good track towards best practice that is used industry-wide by software developers.
With the built in .NET controls, usually you'll have problems if you try deleting fields that have been generated. Your best bet to get things working this way would be to completely delete and re-add the controls you're using, and just try changing the field that you're trying to use a template with. You may still have some issues getting this to work, but shouldn't be too difficult.
Using controls in this way tends not to be flexible, and it's difficult to fix issues. That's why most experienced developers abandon this 'easy' way of doing things, and do database updating manually by creating a form, reading the values and passing this through to a method that will carry out the relevant SQL update. It takes a while to learn but once you get the hang of it it becomes easy and solves so much difficulty trying to grapple with the very .NET specific way you need to work with controls.

Absracting out a Regular Expression in ASP.Net validation

I have searched everywhere and I cannot find a good solution to my problem. I have a regular expression used to validate the text input in an ASP textbox.
Given the fact that this regex is repeated on a number of controls I want to code it once and then call it where it needs to be used. As opposed to repeating the regex across all textboxes, which IMHO is bad practice i.e. if its needs updating then I need to updated it everywhere.
The only possible solution I found was Setting RegularExpressionValidator ValidationExpression at runtime. This does work but I am wondering if it is the only way to do it. The reason being I need to create a RegularExpressionValidator for each textbox control to validate and set the Error message and Expression on each in the Page_Load. Not the end of the world but seems kind of heavy.
Any ideas?
Thanks,
Michael
You could set the value in a constant or static variable. You could then create a class that inherits from the RegularExpressionValidator and set the property to that variable or constant.
Then your custom derived validator will always have that property set.

ASP Net - Casting a Request.Form control from Code Behind

This seems really simple, but for some reason Im stumped..
Im dynamically generating an HTML Select Box, lets call it myselect. Im creating this select box based on some database values Im generating an HTML Select Box.. almost like a string that Im just spitting out to the page. So it's never a control in the codebehind, just part of a string thats rendered as HTML by the browser. If I submit my form, and in my codebehind I perform:
Dim myVal as String = Request.Form("myselect")
That code will give me the VALUE of the myselect select box. How can I refer to this control to cast it as a System.Web.UI.HtmlControls.HtmlSelect control? Request.Form seems to give me the value, but I want to reference the object itself..
If this select box isn't declared statically on your page (that is, you're adding it to the Control Collection), you'll have to do something like this: Dim MySelect as HtmlSelect = Page.FindControl("MySelect") as HtmlSelect
You'll have to forgive me if my casting syntax is a bit off -- I'm used to casting in C#.
If your dynamically generating the control in your code file, then it will not be available to you on post back. As long as you generate it again before the viewstate is processed (you can do it in your oninit), then you can access it as you would anything else.
MySelect.SelectedValue
In response to the comments above (thanks for your help), I found what Gabriel McAdams and jwiscarson had to say were true. In browsing the Request object, I found that its nothing more than a collection of key\value pairs. Performing Request.Form("myformobj") will return a value, because thats all thats available to the application. If necessary, I suppose I can whip up some nifty javascript to track form object types, but it's certainly not necessary in my case.
Thanks for the help

Advice for Building a dynamic "Advanced Search" Control in ASP.NET

alt text http://img3.imageshack.us/img3/1488/advancedsearch.png
I'm building an "Advanced Search" interface in an ASP.NET application. I don't need SO to write this thing for me, but I'm stuck on a specific problem regarding dynamic controls and ViewState. I would like some direction for how to approach this. Here's my situation:
Ingredients:
A serviceable set of API objects representing entities, fields, and searches, which handles constructing a search, generating SQL, and returning the results. So that's all taken care of.
ASP.NET 3.5
Desired Interface Functionality:
(1) On initial page load, the interface gets a preconfigured Search object with a set of SearchCriterion objects. It binds them into a set of controls (see image above.)
Some search items are simpler, like:
Field (DropDownList) | Operator (DropDownList) | Value (TextBox)
Search Criterion controls for some field types have important information stored in viewstate, like:
Field (DropDownList) | Operator (DropDownList) | Value (DropDownList) where the "Value" dropdownlist is populated by a database query.
Some fields are lookups to other Entities, which causes a chain of field selectors, like:
Field (DropDownList) Field (DropDownList) | Operator (DropDownList) | Value
(2) The user modifies the search by:
Adding and Removing search criteria by clicking respective buttons
Configuring existing criteria by changing the Field, Operator, or Value. Changes to Field or Operator will require the control to reconfigure itself by changing the available operators, changing the "Value" input control to a different type, or adding/removing DropDownLists from the "Fields" section if Lookup-type fields are selected/unselected.
(3) Finally, the user hits "Search" to see their results.
The Problem:
As you probably already know if you're answering this question, controls added dynamically to the page disappear on postback. I've created a UserControl that manipulates the control collection and neatly accomplishes step (1) above as you can see in the attached image. (I'm not concerned about style at this point, obviously.)
However on Postback, the controls are all gone, and my Search API object is gone. If I could get the dynamically generated control collection to just play nice and stick in ViewState, I could examine the controls on postback, rebuild the Search object, then handle control events neatly.
Possible Solutions
I could make the Search object serializable and store it in viewstate. Then on page load I could grab it and reconstruct the control collection at page load time. However I'm not sure if this would play nicely with controls raising events, and what happens to the viewstate of Drop-down lists that contain data from the database - could I get it back? It's highly undesirable for me to have to re-query the database on every postback.
I could develop a custom server control (see this link) for this kind of thing... but that is a new topic for me and would involve some learning, plus I'm not totally sure if a custom server control would work any more nicely with non-fixed control collections. Anybody know about that?
I was thinking that I might be able to accomplish this using databound controls - for example I could bind my criterion collection to a repeater which has a fixed control collection (maybe hide the non-used "value" controls, use an inner repeater for the "Field" drop-down lists). Then all the information would stay in ViewState... right?
Any new ideas would be greatly appreciated.
thanks for your help.
b.Fandango
I've been coding for about a day and I got this working beautifully using the third option I suggested in my question - old-school databound controls. Actually I only thought of the idea when I was forced to write out the question in detail - doesn't that just happen to you all the time?
I put my SearchCriterionControl into an asp:Repeater and bound it to my object collection. For the Field Chooser I put an asp:DropDownList inside a nested asp:Repeater and bound the Field array to that. Everything works beautifully, keeps state, actually required very little code. So I never had to dynamically add controls to the page, thank goodness.
Thanks for your suggestions, Ender, Matt and andrewWinn.
Since no one else has taken a stab at this for 2 hours, I'll throw my hat in the ring with a solution that does not rely on viewstate at all (or the ASP.NET model of postbacks).
What if you grabbed all the input values with jQuery and instead of doing a post-back did a post against the page (or a new results.aspx page)? Or, you could make the entire thing asyncrhonous and do an Ajax request against a web method, get fed the results, and populate on the client side as needed?
The unfortunate thing here is you have to reconstruct which type of controls were used to figure construct your search query since that data wont be passed with the viewstate. But I imagine you were already going to have to do some kind of translation of your input data into a query form anyway.
Read here for more information about using jQuery to hit an ASP.NET page method. Remember - page methods must be static (it's an easy oversight).
I'm not sure what you're doing server side to construct your query - but I would highly recommend LINQ. I did a similar "advanced search" function previously, and after a few different attempts found that LINQ was a wonderful tool for this problem, regardless of whether I was hitting SQL with LINQtoSQL or just hitting an in-memory collection of objects.
This worked so well because 1) LINQ is deferred execution and 2) A LINQ query returns another queryable object. The implication here is that you can chain your LINQ queries together as you construct them from your input, instead of having to do a single massive clause translation to SQL or whatever backstore you are using (one of my attempts was constructing SQL clauses with strings, but still passing input data via SQLParameters for SQL injection protection - it was messy and complicated when hand crafted LINQ was orders of magnitude easier to understand and implement).
For example:
List<string> data; // or perhaps your a DB Context for LINQtoSQL?
var query = data.Where(item => item.contains("foo"));
if( {user supplies length search option} )
query = query.Where(item => item.Length < 5);
// etc, etc.
// LINQ doesn't do anything until the query is iterated, at which point
// it will construct the SQL statement without you worrying about details or parameter binding
foreach(string value in query)
; // do something with the results
Because of deferred execution and the queryable return type, you can concatenate LINQ queries to this expression all day long and let it worry about the implementation details (such as converting to a SQL query) at execution time.
I can't provide you with the exact steps that you will need to do, but I HIGHLY suggest looking into asp.net page life cycle. I created a user control as a DLL one time. I had to capture postback data at specific steps in the lifecycle and recreate and rebind the data at other steps. Additionally thinkgs like viewstate are only available at certain points also. I know that I had to override On_init, On_prerender and some other methods.
Sorry I couldn't be more help, but I don't have the code with me (its with an old employer). I hope this helps.
If you are adding controls to the controls tree dynamically, you need to add them on postpack as well. Just call the method that builds the control on Page_Load or Page_Init and the controls should stay on the page on postback.

Why should I create my child controls in CreateChildControls() on a CompositeControl?

Ok so the obvious answer is, because the flow of a composite control demands my childcontrols to be created at a certain point in time. I got a problem i think other people must have had as well.
My control is a composite "container/collection" control. It will be fed with an object and based on that objects data it will create a number of childcontrols. So my control will render a header (always) and x-number of, say TextBox controls (based on the object it was fed with).
I'm creating my header in CreateChildControls() obviously, but i can't possibly create my TextBoxes there as well, because i don't know if the object (to base the TextBoxes on) has been fed yet? I thought of exposing a property/method to set/fed the object through, but i'm not sure when it will be called.
So what do i do? I mean i can't possibly create the TextBoxes in CreateChildControls() or can I? I mean - when is CreateChildControls() called - i know i can call EnsureChildControls() (which i already do in a property to set the innerText of the header - since i need the header to be created before setting its innerText obviously).
How about this
var c = new MyContainerControl();
c.Header = "fun";
c.TextBoxObject = myTextBoxes;
That would raise an error (or at best not create any TextBox'es) if i put the building of the TextBoxes in CreateChildControls().
Would it be more sane to instead just store the Header in a member variable and thus not having to call EnsureChildControls() in the exposed method/property setting the Header innerText. I just don't like this aproach much, since it would be complicating things by adding extra logic to store temporarely and later having to figure out when to set it (probably in PreRender).
Also i guess i could make some kind of Databound control, ensuring the data be present at the time of calling .DataBind(). I really don't like this either since last i looked at creating databound controls it got very complicated.
This really should be an easy task to solve - I know I'm missing something somewhere...
what you're describing IS a databound control. And yes, it's somewhat complicated, but it's the proper design paradigm for this type of instance.
That said, had you considered utilizing the repeater control rather than trying to roll out your own composite which behaves in the exact same manner? Rather than passing it a random object, pass it a collection or an iList with the number of text areas you're wanting.

Resources