ASP.NET Best Practices

Are you sure on this one? I mean, yea, you shouldn’t overuse it, but I think it is has its place in ASP.NET development. For all the resources etc it’s priceless. Plus it really does what you would expect it to do. It renders some text in the Render stage of the Page life cycle, which is IMO good. You wouldn’t suggest to insert a server control in each place a string has to go and fill them on load or by god serialize them into the viewstate of the page.

It should be added that MS included a brand new feature to include resources into pages: <%$ Resources: MyResources, MyText %>.

Valid points about the declarative binding, but I use databinding (<%# something %>) instead.

Funny enough, I started looking around for backup to the “don’t use Response.Write()” and have found nothing official or semi-official indicating it is a bad idea. One wonders if it is actually an urban legend.

You may get away with it directly in the markup like:
<% Response.Write(“Booh!”); %>. It will even work inside some templates, but it will not work with databinding.

Inside the codebehind/codebeside it’s uncontrollable. For example, executed in Page_Init or Page_Load, Response.Write will write text in front of the document declaration.

Nikhil Kothari and Vandana Datye says: “[…] Do not directly invoke Page.Response.Write from your controls because doing so breaks the encapsulation provided by the page framework”.

Generally it’s ill aligned with the page lifecycle. Its not an urban legend.

Databinding expressions though, are perfectly fine. :agree:

I remember seeing an interesting article on a blog titled somthing like “Real Programmers don’t use Response.Write”, I’ll see if I can find it :wink:

Why would someone use Response.Write to output html when you can use the HtmlTextWriter, much nicer IMO.

As for the Server.Transfer, you WILL notice a HUGE difference in server performance if you have a highly utilized website, as Response.Redirect creates a new request which the server will handle.

Also, add a good ol’ true in to your Server.Transfer and your form and querystring collections are retained, no more reading query strings and “re-attaching” them :wink:

Also, in the majority of cases you will be using the transfer mechanism for things like redirecting from a login page to an error page or new home page, and IMO those do not need to be bookmarked at any time :wink:

If one where to use a lot a redirects in an applications I think it’s time to re-evaluate their design because it sure as hell won;t be scalable :wink:

30. Do not cache a database connection in Application or Session objects

Can we get explanations with the rules :smiley:

Cool, I was fairly certain one should not use Response.Write() for the reasons outlined above, but it was a bit shocking to see no confirm why.

We will expain the rules once we agree on them. At the current rate that puts us sometime in 2018. By which time we will have .NET 33.33 which will actually type for us developer types.

30. Do not cache a database connection in Application or Session objects
Doing so will interfere with the ability of the runtime environment to maintain connections in a pool for reuse. It will effectly be locked to your session/application, quickly exhausting pool slots. In fact this it leads to 31:

31. You should open database connections late and close them early.
If you do extensive work between 2 database accesses, you should also consider closing the connection and re-opening it. However, this is not advisable if the to accesses are to be enrolled in the same transaction. Closing a connection effectively returns it to the pool. Opening a connection aquires a connection from the pool.

32. Do not use impersonation for database access.
You may be tempted to use impersonation, and to access the database with the user credentials obtained from the user of the page. This way you could theoretically leverage the security mechanisms of the database server to guard against unauthorized access to data. However, this will defeat the database connection pooling (as each user will require his/hers own specialized connection), and it will affect the scalability of your application.

33. Thy shalt use CssClass instead of individual display properties.
Multiple controls expose properties like BackgroundColor, Width etc. Using these are the equivalent of using Width=xx attributes in html (instead of style=“width:xx”). It is better to just set the CssClass property to a css class name, and define the display attributes in an css. Some controls may have multiple “style” properties. These will generally expose display properties. Same rule goes here. If you are using ASP.NET 2.0 themes/skins this becomes all the more important.

34. (version 2+ only) For databinding use the ObjectDataSource control; limit/avoid use of the SqlDataSource control
SqlDataSource is ok for simple sites (where 3+ tier architecture is not needed) and is actually perfect for prototyping, as it allows you to mock up pages that integrates with data really fast.

However, SqlDataSource promotes a 2-tier architecture. You will end up missing a layer where you can enforce e.g. access restrictions, where you can absorb changes in the underlying model etc.

Using ObjectDataSource will also free the page designer from concerns about the underlying data representation. While the page designer and the developer may be the same person, you’ll often find that you yourself are in different “modes” when tweaking the user interface and designing/coding the business logic.

To leverage the ObjectDataSource you will typically

  1. design/implement classes representing entities of your model
  2. design business logic classes which expose methods to create, read, update, delete entities and to execute business actions (cancelling an order may involve manipulation multiple entities).

If you design the business logic classes so that they have a public default constructor (no parameters!), they can be leveraged immediately by the ObjectDataSource control. This means that the business logic class must obtain connection properties itself. The connection strings in web.config are ideal for this, i.e. the business logic class discovers the actual database connection string using a well-known name (like “OrderConnectionString”).

I have to agree with Dangermouse here, in that we (the new and less experienced) could definitely benefit from some more detailed explanations and examples of these so called Best Practices.

I’ve wondered why it always is that these “Best Practices” are so enured in the negatives? Thall shalt not this…

Is there some rule against saying something like Thall shall do it this way and illustrate how it should be properly done from a more positive stance and then give the “But if you don’t, be prepared for the worst…” rather than focusing so much on the negative first?

Okay my turn. Any particular reason why you say that?

  1. First you guys say “Thall shalt not use user controls…” and now the above rule says we should. Hello? Am I the only one who sees a Contradiction here? Could someone please clarify a little or at least put some qualifiers on when we should and shouldn’t use user controls in favcr of a Master page?
  2. I find this rule completely confusing considering I am reading a Beginning ASP.NET book put out by Microsoft Press where it states that the use of <!–#INCLUDE –> is not only perfectly acceptable, but the PREFERRED METHOD of doing this for the confines of the book so now our Best Practices are contradicting one another again. This would be a great place for some examples and explanations.
  3. Also, all the tutroials and examples/tutorials I have seen regarding setting up/using/designing Master Pages have been confusing to say the least so here again is where more explanation and good solid examples would be supremely useful.

while i totally agree, MS for some odd reason puts default styles on a good deal of its controls and will override your class styles unless you ! important by those default attribute defined in your css class or create your own version of controls like the calendar control and override the defaults (i.e this.ForeColor = Color.Empty) . The font-colo/ForeColor attribute of a alot of controls are pre-set, like validators. another issue is that they often output tables with no summary attribute. =(.

but this is defintely a good practice as you abstract styles from your presentation layer, enabling you to make global changes to the whole website, quicker, uniform, and more accurate. Good job.

This is a collabarative effort. Some of the “best practices” reflect individual experiences and/or preferences. Like a wiki anybody is free to contribute. Given that, you should regard these “best practices” as suggestions. They are open for debate. I myself have chimed in on a few of them.

Actually I disagree with the “Thou shalt only use user controls when it is required on more than one page”. I find that user controls offer a great way to separate concerns. IMHO there are many valid reasons to use usercontrols beyond the simple cross-page reuse:

  1. if an area of the page has a complicated UI logic which integrates several elements, but at the same time have few references to other elements/areas. In this case I find that seperating the inter-control UI logic into a usercontrol improves readibility and maintainability.

  2. usercontrols also defines pagelet cache boundries. If the output of the usercontrol is a) expensive to generate, b) cacheable and c) the page itself is less cacheable, the performance gain from a usercontrol can be enormous.

  3. if I want my page to have a special “mode” where part of the page is obscured by e.g. a temporary wizard/view, I’ll often seperate this temporary wizard/view out into a usercontrol. True, I could just define the wizard/view in a panel which would be visible only when I wanted the temporary mode. But by using a usercontrol I can add/remove the extra control dynamically, thus avoiding viewstate/controlstate pressure from the extra functionality. Often I’ll have multiple alternative views seperated out in usercontrols.

  4. I may want to have a “pluggable” architecture, e.g. different “viewers” for different product classes on an online shopping site. A pizza should come with the option to customize the toppings, while the coke should have only the “size” option. I may realize that I cannot tell in advance exactly which and how many product classes I’ll need viewers for. Hence, I want an architecture where I can add a new product class simply by adding a new viewer usercontrol.

On the <!–#INCLUDE –>, I find it generally undesired in ASP.NET applications. I have yet to see a good example of a problem solved with SSI which is not solved better using one of the higher level techniques. But that’s just my opinion. :wink:

Wow, looking back, that one hurt. :blush: But you are oh so right. Somehow it’s easier to make rules for what not to do. Like “thou shall not kill”. I hope that it is because there’s still infinitely many more ways to do things right than it is to do them wrong?

Can we have more of these: If xxxxxx is what you are set out to do, then yyyyyy?

I think the “Thou shalt not” was just done in fun. It wasn’t meant to infer that you must absolutely do it this way or you are wrong.

:slight_smile:

As I am still sort of fairly new to programming as a whole, I thought we were pretty much dealing with absolutes in a lot of this stuff. My apologies…

I must agree, that without an explanation of the underlying reasoning, it’s easy to take the statements as absolutes. You simply have no way to validate whether your particular problem is covered by the reasoning or not.

I encourage all posters to include a few line of discussion/reasoning/explanation. The do/do nots should be explained by why/why nots.

Explanations are good. Here are mine, reprinted for convenience:

  1. Thou shalt not use exceptions to manage program flow.

Throwing an exception is a very expensive operation–basically the most expensive thing short of calling external resources. Think of an exception as making the computer beep twice and pause for two seconds, then think if you actually want to use one in that place.

  1. Thou shalt wrap calls to external resources, such as configuration values or session variables in strongly typed properties.

The idea here is to facade things like the Session object away. For example, add a property to your base page class such as the below:


protected string UserName
{
	get 
	{
		string ret=Session["username"];
		if (ret==null)
			ret=string.Empty;
		return ret;
	}
  	set 
	{
		Session["username"]=value;
	}
}

This means that your application no longer has to worry about the specifics of the username storage, it just pulls the property. So when you decide that it is better to store it in a cookie, all you need to do is change the property. Moreover, when one is storing complex types, it centralizes all the casting.

  1. Thou shalt not use DataSets in web applications.

We had a nice little debate on this subject on page one. In general, one does not want to use data sets even if they make things nice and easy. The main drawback is that architectually, using a dataset means the front end application is quite aware of the back-end database and business logic tends to bleed into the presentation layer. One ends up with a 2.5 tier solution oftentimes. The other major disadvantage of a dataset is they tend to get very inefficent, especially for large datasets. Bottom line is to only use them where having an in-memory representation of the database makes sense.

  1. Thou shalt use common sense.

I hope this transtlates . . . .

  1. Thou shalt not use Server Side Includes (<!-- #INCLUDE –>). Thou shalt use user controls or master pages.

Best explained by Benjymouse above.

  1. Thou shalt not use Response.Write. This includes the shorthand <%= somestuff %>.

Also debated & explained above. One should never, ever use Response.Write() in the code behind/code beside parts of a page (that is the back-end code) as it does horrid things to the .NET page lifecycle model. If one must emit text to the output stream, send things to the HtmlTextWriter that stores the response instead.

Inline the debate is a bit thicker. I, myself, use databinding (<%# somestuff %> to page-level variables rather than including calls to Response.Write (which can be shorthanded as <%= somestuff %>).

Hope this helps.

So only use them if you have to do something sort of like paging a recordset? Say you have a catalogue of the 300 DVD’s in your collection which you want to display to the user 50 at a time?

Not quite, as that is a rather simple database hit. Much more useful in situations like benjymouse explained where one needs repeated, random access to the data.

Furthermore, DataSets really start to creak when they get large.