Strategic Advice: Upgrading the Design of a Web App - asp.net

I have an ASP.NET web site dedicated to reporting on PBX extension stats. It comprises many report pages, with HTML generated almost purely by code-behind (setting a Label control's Text property instead of using Response.Write), using un-parameterised string literal SQL queries that populate By Reference DataTable parameters.
Maintenance pages at least comprise DataGrids and detail forms, but use the same DAL, on e thing for which can be said is that it supports multiple DB servers, with sub-classes each overriding these access methods with their own string literal queries.
What do I need to consider cleaning up this mess? I've already made an almost obvious decision to use a third party reporting solution, and move the queries to stored procs in their respective DB languages, narrowing the diversity of the different DAL classes, and to separate CSS out to shared files, as lots of it is very hidden in C# files!

For your back-end design, I suggest having a class to represent each main table of your database (i.e. a Report class and a User class, for example). Anything that's not an event handler should go in the back-end class files / namespace.
For your GUI, looks like you're on the right track using ASP.NET controls instead of just streaming your data out to the user. However, you may consider objectifying the areas of the page. For example, one of my favorite tricks is to open semitransparent "popup" panels when requiring user input or a something like the Information Bar when displaying a short message.
Consider AJAX and the AJAX Control Toolkit. It's easy to implement (especially in the case of a rewrite) and provides great flexibility. Specifically, I've found Accordions - sometimes even nested within other Accordions - are excellent at organizing overabundances of information.
Edit:
Note that if you were to use AJAX, you basically can't even consider using response.write anymore.
As far as having too much content on the screen, remember Panels have a "Scrollbar" property and DIVs don't without some heavy changes.
Also, I tend to separate my code files by Namespace; but the popular trend is to do so by Class. This is a better option if you have many Developers or if it's likely several classes within a namespace will be checked out or simultaneously modified by different people.

I would consider ditching any custom written DAL and use one of:
iBATIS.NET
NHibernate
SubSonic
You might even end up dropping sprocs entirely.
If you're daring you could try the redesign using Microsoft's MVC implementation.
Whatever approach you take, make sure you write unit tests prior to refactoring any code, verify the tests pass before and after refactoring.

Related

When creating web pages, what is the recommended approach for Add/Edit?

Lets say you are developing an web app that requires that you are able to Add/Edit items. The item form contains several input control. Would you separate the add/edit pages or use the page for add/edit and control via querystring (i.e. ItemAddEdit.aspx?isEdit=1)
The advantage I see in separating is that it is easier for the (non-technical) user to type the page and to determine whether it is add or edit. Also, when there would be specific changes to each page (if ever), it would be easier to change.
For the single page, well, you reuse code which eliminates some duplicate code and avoid possible problems.
And no, I can't use routing.
This is generally something which could be a subjective thing, because there's as many ways of doing things as there are coders, and a lot of it can be depending on how your system is set up generally.
But, if I were to recommend, I'd say the way you should do it if working with asp.net web-forms is to make two web pages (add/ edit) and then you use a user-control on those to group up the shared logic between the two pages. After all - that's why we have user controls.
In this way you can have both of your situations, by keeping logic in one file/class, but still have two entry points.
This would also mirror more how MVC does it, which could be considered a plus.
That being said - if your administration functionality is behind login etc, there's nothing to hinder for actually doing it in one and separate with the query string approach, and then just load the data if editing or display "empty"/base data when creating.
You shouldn't have the user type the addresses anyway, but click through the links to follow your flow, so the query string should be a minimal issue.
But for the sake of keeping your functionality clean and divided, I'd personally recommend going for two page / usercontrol approach.

Advantages and disadvantages of usercontrol in asp.net

Can some one please tell me if I should use user controls in my project as much as I can? Ff so why and if not why not?
It's an interesting question; but think of it this way.
You've just written a table, listing all of your users. You show this on the List Users page of your website.
On the "Find User" page, you might want to be able to show a list of users. Do you rewrite the same HTML, code, javascript, CSS as before? Or do you reuse the control, this time adding the ability to filter by a user name or other attributes?
Essentially, user controls are there to package up reusable bits of your website. Rather than repeating the same code everywhere, you can package it up in a user control, and simply add it to any page you want just by adding the appropriate tag.
Also, you have just made ONE control in your project responsible for dealing with some functionality - all of the logic for it is in one place and separated from other code. This is an important concept too, as it stops all of your code being jumbled together. In the users example, you can interact with a list of users through an interface, rather than mixing it with other code that might do different things. This is called SRP and can be a good thing.
As a practical example, we have a control that shows a list of our products. We can reuse the same control on the Find screen, the Admin screen, the "Products Like this" screen, and on the "Products you have chosen" screen. This code contains a lot of logic that is all in one place so it can be maintained easily, and it can be reused very simply too.
User Controls can be a very good thing. So you should use them when you feel like you can package up a group of existing controls, HTML etc. It makes them reusable, and much easier to maintain.
There is also the concept of custom controls - these are usually reimplementations of existing controls - you might have an ExtendedTextBox, for example, that validates the text as someone types it.
You can read more about both kinds of controls here
User controls are good for the same reasons that subroutines/functions/methods are good: code (and markup) re-use.
Like subroutines, controls can be a problem if they do things like modify global state, make lots of DB or other off-box calls that aren't always needed, introduce unavoidable synchronous blocking, etc. They can also add an unnecessary layer of complexity if they are never re-used.
I would use the controls that the VS IDE Toolbox provides as much as possible. I would only roll my own control if something that the environment supplied, didn't quite do what I wanted it to do.

ASP.NET UI Customization

In my application, I have a situation wherein the users will need to have the flexibility to customize the UI to a certain extent. The following are some of the customizations that is being discussed now...
Change Label text associated with the with Use Input controls
Mark a control as Mandatory/Read only/Hidden
Assign a regular expression for the text box
Are there any recommended design patterns for my situation? Seems like I need to store all these in a database and worried about the performance impact if I have to read every element from the database for every page.
Thanks,
Harsha
I would look at some of the open-source CMS or portal systems written in ASP.NET and see how they are doing UI customization (if they are).
Phil Haack has some insight at the following article:
Scripting ASP.NET MVC Views Stored In The Database
http://haacked.com/archive/2009/04/22/scripted-db-views.aspx
Apparently it's not an easy thing to do in ASP.NET. It's easier to do in ASP.NET MVC, because the markup is cleaner and you can control it with jQuery.
The overall concept you are going for is not easy to have system wide, however the specifics you stated are fairly easy.
You'd have to setup some fields in a database for those values and then on the page load set those values on the page load. Pretty trivial from a 'how to'. Which your question shows that you 'get'.
Now unless you are using an Access Database :-), I don't think you have to worry about the performance hit. But if truly concerned, put some caching logic on those values so you only have to hit the database once. Though, be aware this will store the values in memory on the server, so if you are working with a very minimal hardware this could be an issue as well.

Building ASP.NET application - Best Practices

We are building an ASP.NET application and would like to follow the best practices. Some of the best practices are:
Server side Code:
Use catch blocks to trap & log low level errors too.
Use Cache objects to populate dropdowns etc. where we won’t expect the changes in the underlying data/database.
In case of error logging framework, provide emailing alerts along with logging the errors.
HTML code:
- Don’t write inline CSS.
- Place the JavaScript code (If needed by the page) at the end of the page unless the page needs it for load time actions.
Now coming to the point, Would you please share these best practice points if you have a comprehensive list of them already?
Some of the best practices that I've learned over time and written up for use at my company...many are mainly applicable to WebForms and not MVC.
Don't write .NET code directly in
your ASPX markup (unless it is for
databinding, i.e. Evals). If you
have a code behind, this puts code
for a page in more than one place and
makes the code less manageable. Put
all .NET code in your code-behind.
SessionPageStatePersister can be used in conjunction with ViewState
to make ViewState useful without
increasing page sizes. Overriding
the Page's PageStatePersister with a
new SessionPageStatePersister will
store all ViewState data in memory,
and will only store an encrypted key
on the client side.
Create a BasePage that your pages can inherit from in order to
reuse common code between pages.
Create a MasterPage for your pages
for visual inheritance. Pages with
vastly different visual styles should
use a different MasterPage.
Create an enum of page parameter key names on each WebForm
that are passed in via the URL, to
setup strongly-typed page parameters.
This prevents the need for hard-coded
page parameter key strings and their
probable mis-typing, as well as
allowing strongly-typed parameter
access from other pages.
Make use of the ASP.NET Cache in order to cache frequently used
information from your database.
Build (or reuse from another project)
a generic caching layer that will
wrap the ASP.NET Cache.
Wrap ViewState objects with Properties on your Pages to avoid
development mistakes in spelling,
etc. when referencing items from the
ViewState collection.
Avoid putting large objects and object graphs in ViewState, use it mainly for storing IDs or very simple DTO objects.
Wrap the ASP.NET Session with a SessionManager to avoid development
mistakes in spelling, etc. when
referencing items from Session.
Make extensive use of the applicationSettings key/value
configuration values in the
web.config - wrap the
Configuration.ApplicationSettings
with a class that can be used to
easily retrieve configuration
settings without having to remember
the keys from the web.config.
Avoid the easiness of setting display properties on your UI
controls, instead use CSS styles and
classes - this will make your styles
more manageable.
Create UserControls in your application in order to reuse common
UI functionality throughout your
pages. For example, if a drop down
list containing a collection of
categories will be used in many
places in the site - create a
CategoryPicker control that will data
bind itself when the page is loaded.
Use Properties on your UserControls to setup things like
default values, different displays
between pages, etc. Value type
properties can be defined on your
UserControls and then be set in your
ASP.NET markup by using class level
properties on UserControls.
Make use of the ASP.NET validation controls to perform simple
validations, or use the
CustomValidator to perform complex
validations.
Create an Error handling page that can be redirected to when an
unhandled exception occurs within
your website. The redirection can
occur via the Page_Error event in
your Page, the Application_Error
event in your Global.asax, or within
the section within the
web.config.
When working with pages that use a highly dynamic data driven
display, use the 3rd party (free)
DynamicControlsPlaceholder control to
simplify the code needed to save the
state of dynamically added controls
between postbacks.
Create a base page for all your asp.net pages. This page will derive from System.Web.UI.Page and you may put this in YourApp.Web.UI. Let all your asp.net pages dervice from YourApp.Web.UI.Page class. This can reduce lot of pain.
Use Application_OnError handler to gracefully handle any error or exception. You should log the critical exception and send the details of the exception along with date-time and IP of client to the admin email id. Yes ELMAH is sure way to go.
Use ASP.NET Themes. Many developers don't use it. Do use them - they are a great deal.
Use MembershipProvider and RoleProvider. And Never use inbuilt ProfileProvider - They store everything in plain strings. It will drastically slow-down the performance while performing R/W
Use Firebug for client-side debugging. Try to follow YSlow standards for web-applications. Use YSlow extension for FireBug.
Use jQuery for client-scripting.
Never store User Authentication information in session or don't use sessions to judge if user is logged on. Store only minimum necessary information in sessions.
Have a look at PostSharp. Can improve maintainability of your code and make you more productive.
Never ever Deploy asp.net application under debug configuration on production. Find out here what scottgu has to say about this.
User Web Deployment projects. It can transform web.config sections and replace with production server setings. It will merge all compiled code-behind classes into one single assembly which is a great deal.
Use Cookie-less domains to serve static resources like images, scripts, styles etc. Each client request is sent along with whole bunch of cookies, you don't need cookies while serving pictures or scripts. So host those resources on a cookie-less domain.
Minify scripts, stylesheets and HTML response from the server. Removing unnecessary line-breaks and white-spaces can improve the time-to-load and bandwidth optimization.
Forms:
Set Page.Form.DefaultFocus and Page.Form.DefaultButton to improve user experience
Check Page.IsValid in your Save button handler before proceeding.
General:
Understand and implement the techniques found in the article "TRULY Understanding ViewState"
Use Page.IsPostBack in your page events to stop code from running unnecessarily.
Use hyperlinks instead of posting and using Response.Redirect whenever possible.
a. Understand and use the second parameter of Response.Redirect (it "Indicates whether execution of the current page should terminate")
Use the Page Lifecycle properly.
Use the Per-Request cache (HttpContext.Items) instead of Cache where it makes sense.
Web.Config:
Deploy with <compilation debug="false">
Register your controls at the web.config level instead of the page level (i.e. #Register).
Themes:
When using Themes, put your static images in the Theme as well.
a. Don't link to the images directly from your markup, link to them from a skin file or css file in your Theme instead.
ex: <asp:Image SkinID="MyImage" runat="server" ImageUrl="Images/myImage.gif" />
I don't think try/catch blocks are always appropriate for low-level methods. You want to catch (and log/alert, even better!) any errors before they get to the user, of course. But it is often better for a low-level method to just lets its errors get raised up to a higher level. The problem I have seen with low-level error trapping is that it often lets a larger operation continue, but then a result that is not quite correct gets presented to the user or saved to the database, and in the long run it's much more difficult to fix. It's also just a lot of extra clutter in your code to put a try/catch at every level if you're not going to "do anything" with the error until it's raised up to a higher level.
Here are some similar questions that may help you.
.NET best practices?
Best way to learn .NET/OOP best practices?
This should probably be community wiki as well.
I would recommend a couple of books if you are interested in pursuing a journey to become a better, more productive developer. These books are language agnostic and as you can see by the user reviews, very very helpful.
Code Complete 2
Pragmatic Programmer
If you are looking for a .NET specific book, you may appreciate the following book:
Microsoft Application Architecture Guide [available online for free outside of print format]
ASP.NET
If you don't use Session state, don't
forget to turn off it.
Use Server.Transfer instead of Response.Redirect if possible.
Set expiration parameter in IIS.
Use GZip to compress the text files.
Use Server-Side and Client-Side validation together.
Use Url Rewriter or Routing to make friendly url for SEO.
Design
Write each class and its properties
of your CSS file in the same line. (To decrease the file size)
Use CSS Sprites. (To decrease request)

What are the benefits of an XML data model over the DataSet model?

At my current job we have a CMS system that is .NET/SQL Server based. While customizing a couple of the modules for some internal use, I was a little surprised to see that instead of having APIs that returned data via your typical result set that was bound to a DataGrid/DataList/Repeater control, that the APIs returned an XML node/collection, that was then passed to an XSLT transformation and rendered on the page that way.
What are the benefits to using a model like this?
Using XSLT transformations would enable you to use a different layout and formatting than the standard .Net grid controls. Some people don't approve of using the .Net grids because they can include more HTML than necessary, and because if not managed carefully, they can bloat ViewState.
There was a recent discussion here about the .Net grids being bloatware (but developers use them anyway).
The outputted pages can be of any type, like html, php, etc.
By setting up the datasource and xml that the page merely transforms, you have also instantly created a simple 'web service' that can be consumed by other software. For example, it would be trivial to turn that grid into an rss feed or write a program to scrape that data periodically and send a more pressing alert.
The XSLT method is very MVC, unit-testing, separate-concerns friendly where ASP.NET controls well... aren't.
caveat: I reject the assumption that MS can write better html/css/js than I can. ASP.NET controls are clunky abominations.

Resources