Inflection Research

June 2, 2008

Web Application Standards

Filed under: Programming, Web Platform — semanticzen @ 1:42 am

It is important that mid-size to large enterprises build applications consistently. When a company has hundreds of applications to maintain it is important to re-use solutions. These re-usable solutions include common code such as an enterprise library or consistent design patterns. An enterprise library should include an application block as well as re-usable web services, business objects, and controls.

By re-using solutions programmers can seamlessly move from maintaining one application to another; and more junior programmers can learn and maintain complex applications much easier. Application standards are never static, but evolve over time. So it is important to revisit them regularly. With technology, in time practically everything changes (even design patterns evolve over time).

It is important to use best practices to re-use patterns and practices that experience has shown to be most effective. However, best practices are not a pretext preventing creative solutions to new business problems. Best practices exist to handle the repeatable problems so project development teams can focus on application specific issues. Best practices should never inhibit creativity.

It is wise to ensure best practices are followed through periodic code reviews. However, no one likes code reviews. Not the person getting reviewed and not the reviewer. So it is advisable to focus on what is important and not be nitpicky when it comes to performing a code review. Time permitting it is better to sit down with the programmer and go through and discuss the code together.

Good rules help keep the quality of programs high while not being so restrictive to inhibit creative problem solving. Below are the ASP.Net web application standards I have compiled.

 

 “Good architecture is necessary to give programs enough structure to be able to grow large without collapsing into a puddle of confusion”

-Douglas Crockford, Creator of JSON

 

Application Goals

I.    Usability

  • About the user experience including user interface design plus application flow, availability, and performance
  • Efficiently fulfill the business requirements
  • The user interface should be simply self-explanatory

II.    Maintainability

  • The vast majority of an application’s life is spent in the maintenance phase; it is critical that the application’s maintenance s as simple as possible
  • A good application is flexible because it is object-based and event driven enabling it to be straightforwardly extended and tested

III.   Time to Market

  • The waterfall method of building applications is dead; application features should be released early and often, increasing user feedback and minimizing scope creep

 

 

Goals for these Standards

  1. Consistently implement best practices
  2. Use and contribute to the company’s enterprise library
  3. Build high performance applications while minimizing complexity

 

 

Goals of Software Architecture*

  1. How to best partition a system
  2. How components identify and communicate with each other
  3. How information is communicated
  4. How elements of a system can evolve independently

*From Roy Thomas Fielding’s (Chairman of the Apache Foundation) doctoral dissertation about web application architecture

 

 

Prerequisites

I.    Project Kickoff Prerequisites

  1. You have read and understand the web application principles (this document)
  2. You have worked with an architect to create a high-level object design for the application

II.    Code Review Prerequisites

  1. You have generated a Visual Studio 2005 class diagram
  2. You have run the Visual Studio 2005 code analysis
  3. Review the Web Application Standard’s Code Review Checklist (below)

 

 

Code Review Checklist

Your code review will fail and your application will not move to production if you do not follow these standards.  If you have any questions or concerns do not hesitate to discuss them with an architect.

I.    Application Setup & Straightforward Code

  • Does your project use the page and project defaults?
  • Is your code straightforward and as simple as possible?

II.    Object Oriented Design

  • Is your application a group of objects or an incomprehensible mess of code?
  • Is your .Net code, HTML, JavaScript, XML, XSLT, CSS, etc. in separate files?
  • Did you copy and paste any code? (Bad!)
  • Did you re-use code?  How?

III.    Enterprise Library

  • Are you using the enterprise library’s objects, web services, and controls whenever possible?
  • Are you using the standard UI framework, which should contain the only default styles in your application?
  • Did your application contribute code and functionality to the enterprise library?

IV.    Best Practices

  • How are you managing state?
  • Are you caching common data?
  • Is the code documented and understandable?

V.    Application Optimization

  • Did you optimize the frequent code paths?
  • Did you run the Visual Studio 2005 Code Analysis?
  • Did you run a search to find code that shouldn’t exist and code that should exist?

 

 

Best Practices

I.        Application Setup

The programmer should review this list before an architect performs a code review

A      Page & Project Defaults

  1. Turn off view state, unless it is required: <%@Page EnableViewState=”true”%>
  2. Your application should have a default file so your users can just go to http://intranet/{your application name}.  They should not have to go to a home page like http://intranet/{your application name}/ASPX/MainFiles/MyCrypticStartPage.aspx
  3. Every page much enforce page level security by checking the user against an Active Directory group
    1. In test you must use the “_test” suffix for every group name
    2. In development, give all developers and CA’s access to your application by putting the ESSTEST active directory roles Internet Developers and Consulting Analysts in your application’s most junior role
  4. A project should not contain code or files that are not used, source control should be used to archive old code
  5. A web form’s code behind should only contain code that directly manipulates web controls or the HttpContext
    1. Additional logic must go in a separate object
    2. Do not pass business objects the HttpContext object (or other child HTTP objects)
  6. All new applications must request a new id to access the database

B       Straightforward Code

Good code is self explanatory.  Use the Xml documentation capabilities built into Visual Studio (hint: VB uses ”’ and C# uses ///)

  • Comments
    • Explain the code; do not repeat it; good code (readable names and straightforward organization) is self-explanatory 80 – 90% of the time
      • Do not provide obvious commentary such as “executing stored procedure” or “loading XML document

      • For code that is specific to one application only document assumptions or difficult algorithms
      • For API code provide extensive documentation and possibly some examples
    • For .Net code add Intellisense documentation on complicated or re-usable functions, properties, classes, etc
    • Courteous Commenting
      • Use end-line comments only on variable declaration lines (end-line comments are comments that follow code on a single line)
      • Do not create formatted blocks of asterisks that surround comments
      • Begin the comment text with an uppercase letter and end the comment with a period
    • Organize large classes with #Region and provide a brief description of the region
  • Formatting Code
    • Use empty lines to segment code where appropriate
    • Remove old, unused code
  • Document
    • Outline and describe any new common web services, controls, or objects that can be shared
  • Naming Conventions
    • Follow the naming convention rules enforced in the Visual Studio 2005 Code Analysis
    • Prefix private global variables with “m_” (like m_WebServicePath) à minimize their use
    • Use descriptive variable names
  • Avoid hard coding
    • Connection string or server specific configuration settings should be in the machine.config and prefixed with the application name
    • Other application specific configuration should go in the web.config

C       Straightforward UI

  • The application should have rules
    • If the user can do something on one screen she should be able to do it on similar screens
    • The user should be able to quickly understand what they can and cannot do (and why)
  • In a workflow, make the steps obvious or explicitly define them upfront

 II.    Object Oriented Design

An application is a grouping of objects, services, events, and processes.  It is important to encapsulate each piece and expose it through an easily understandable interface.  This enables code re-use and allows for easier maintenance as the code can be learned or replaced in discrete slices.

 A      Basic OO Guidelines

Encapsulate functionality into logical objects.  In the web paradigm, inheritance is depreciated; encapsulation is easily the most important OO fundamental.

  • The class that manipulates the user interface should contain no business logic
  • A method should only perform 1 task
    • Avoid long methods (over 50 lines is too long, 20 lines is a good rule of thumb)
    • Avoid methods with more than five arguments (encapsulate additional data in xml or a struct)
  • Don’t repeat the same code in your application or across applications
  • Objects should be loosely coupled

B       Distinct Application Layers

Encapsulate the distinct application layers (business, data, and presentation). 

  1. The user interface should not include business logic.  Do not put application logic in JavaScript.  If necessary, call a web service to calculate business logic.
  2. When possible use metadata when processing business rules.  It is much simpler to update the metadata in a database or configuration file than modify code.
  3. It is still important to place the processing close to the resources it needs.  If performing bulk updates (updating hundreds or thousands of rows) it probably makes sense to put that logic in the database as perhaps a stored procedure or SSIS package rather than putting in an application server.
  4. Avoid putting client-side presentation (HTML, CSS, etc) or behavior (JavaScript) in server side code.
  • Put content in ASPX, ASCX, HTM, or XML files
  • Put logic in .VB or .CS files
  • Put data in the database or XML
  • Put scripts in separate JavaScript files
  • Use CSS files to style HTM, use XSL to style XML 

C      Code re-use

  1. Watch out for a copy and paste mentality.  Copy and paste is not code re-use, it is code duplication
    1. If you find yourself copying and pasting, wrap this functionality into a re-usable object, control, or web service
  2. Ensure you are not writing code that is already available in another component or in the .NET framework
  3. Organize and encapsulate all code into objects or structs
  4. Look for repetitive code that could be written as a common function or object
  5. Do not hard-code values; if necessary create a constant or readonly variable, or encapsulate related parameters or variables in a struct

 D      Questions

  1. Are you encapsulating functionality within a discrete object or resource?
    1. Avoid complex object graphs which are harder to maintain and create more work for the garbage collector.
    2. Do not reference short-lived objects within long-lived objects.
  2. Are your methods encapsulated?
    1. Are you using external variables not passed into the method?
    2. Limit or preferably eliminate the use of global variables.
    3. Are your methods too long?
  3. How are you grouping and exposing functionality?
    1. Are your object, method, property, and variable names intuitive?
    2. Are you adhering to a namespace hierarchy?
    3. Are the objects, methods, properties, and services easily discoverable?
    4. Are you using inheritance to group similar objects?
    5. Are you using the correct scope (public, friend, protected, private) for objects, functions, fields, etc
    6. Are your objects and resources available through an easily discoverable and understandable interface or web service?
  4. Class design:
    1. Are you using a constructor to set class level variables? 
    2. Are you using a destructor or finalizer to clean up expensive resources?
    3. Are you properly declaring access modifiers for your methods, properties, fields, and structures?
  5. Are you overusing a certain technology?
    1. Performance problems may arise by using a good technology in the wrong situation.

 III.    Enterprise Library

 A       Use an Application Block

This component is an application block and it must be used when:

  • Connect to the database
  • Error Handling & Logging
  • Send output or communicating with people or other applications: E-mail, FTP, HTTP posts, etc
  • Impersonation
  • To lookup values in Active Directory

*You should have documentation available for re-usable code such as your application block and re-usable business objects and web services.  The below information includes some basic functionality you will want to include in your common objects and services.

  1. Data Layer
    1. When connecting to SQL Server use these methods
  2. Error handling
    1. Code that is prone to fail (e.g. database calls, etc.) should be wrapped within a Try…Catch…Finally block; to provide maximum debug information.  
    2. Only catch errors (and not re-throw) if you have explicit handling. 
    3. Avoid defining custom exceptions.
  3. Logging and Tracing
    1. It may be beneficial to have custom error logs for every .NET application.
    2. Enabling a trace will allow the developers to debug production problems.
  4. Authentication, Authorization, and Active Directory
    1. Unless some other requirement dictates a custom authentication and authorization mechanism, AD should be implemented.
    2. In a case where Active Directory is not used, ensure that confidential information is encrypted.

 B       Use a Common Theme

  1. This theme must be every application’s default theme
  2. You will need to install it locally on your machine in:
    1. c:\winDOWS\microsoft.NET\Framework\v2.0.50727\ASP.NETClientFiles\Themes
    2. c:\Inetpub\wwwroot\aspnet_client\system_web\2_0_50727\Themes
    3. Reference the theme in your web.config:  <system.web> <pages
      theme=YourTheme> </system.web>
    4. Do not use an App_Theme folder in your project
  3. If you need to override the standard theme on your page create your CSS file so it references a specific className or id, so by default your page will use the standard theme except where you specifically dictate it not to

    *It is often a good strategy to not implement your common UI framework through an ASP.Net theme, but instead through a common CSS file and a shared directory of JavaScript, images, and HTML files. This provides the flexibility of implementing your UI framework across different web application technologies and different ASP.Net versions.

 C      Use Common Web Objects & Services

  1. Use to log errors or debug information to a central repository
    1. There is a UI to view this logged information
    2. Can setup yourself to receive alerts based on what information is logged
  2. Can track website usage
  3. Can call a long running stored procedure through a generic web service
  4. Or add new common functionality
    1. Use when a method or stored procedure may be valuable to expose to other application as a web service
    2. If Xml is the input or output of the web service please provide an xml schema
      1. Regardless, it is a good idea to use a schema in the design process.
      2. From a security standpoint it is a good idea to use a schema for validating input

 IV.    .Net Best Practices

 A      Web Paradigm

  1. Make sure your application supports the back and forward button
  2. Use meaningful URL’s
  3. Ensure your application has a useful default page
  4. When possible build stateless web pages

B       Caching

  1. Consider caching drop downs or other data that seldom changes
  2. If data can be used by multiple requests and is not user specific it is a good idea to consider caching
  3. Before using a cached object, verify that the object is in the cache and if not allow easy recreation of the object

C      Session Management

  1. Encourage stateless development when possible
  2. Do not use the session object
  3. Disable view state except when it is required

 D      Controls

  1. Ensure that the developer uses the right control in the right situation
  2. If the same set of controls is being reused between pages, a user control may be more appropriate
  3. Scrutinize the size of the view state, and make suggestions about enabling or disabling this attribute per control

 E       SQL Transactions

  1. If a transaction encompasses only updates to a single database, perform the transaction on the SQL Server in T-SQL
  2. If a transaction is spread across multiple data sources or involves something that does not inherently support transactions, the transaction should be performed by ADO.NET

F       Data Retrieval

  1. Use the Data class found in the company’s application block
  2. Use disconnected recordsets, via the DataTableReader, DataTable, DataSet, XML, or JSON
  3. When you do not need a recordset returned use ExecuteNonQuery or ExecuteScalar and use output parameters
  4. Rather than make several database roundtrips, return multiple result sets from a single stored procedure

 G      Data Binding

  1. The DataBinder.Eval method uses reflection to evaluate the arguments that are passed in and to return the result
  • If you have a table that has 100 rows and 10 columns, you call DataBinder.Eval 1,000 times, if you use DataBinder.Eval on each column; your choice to use DataBinder.Eval is multiplied 1,000 times in this scenario
  • Limiting the use of DataBinder.Eval during data binding operations significantly improves page performance
  • Consider either explicitly casting or using the ItemDataBound event as an alternative

 H      Web Services

  1. Consider using the OneWay attribute on Web methods or remote object methods if you do not need a response
  2. If consuming a long running web service or don’t need a response consider calling the web service asynchronously
  3. Use the company’s standard namespace:  http://www.YourCompany.com
  4. For web services consumed by multiple clients always provide a method description
  5. For communicating with the web server from the client’s browser through remote scripting calls use Ajax ASP.NET

I         Connection Pooling

  1. Verify that all connections are opened just in time and that all connections are closed as early as possible
  2. Whenever a connection is being opened ensure that the connection will be closed through the use of a finally clause or the Using statement 

J        Grids

  1. For updateable grids that can be IE specific use DHTML data binding for browser independent updateable grids use the GridView control
  2. If the information is read only use a repeater or GridView control 

K      Memory Management

  1. Employ the Using statement when using objects that need to be disposed of quickly
  2. If your object opens external resources implement a Dispose method to close the external resources

L       Asynchronous Pages

  1. Useful when more than 1 database call or long running processes are required
  2. Allows better thread management for the web server
  3. Increases throughput because requests it reduces the amount of time pages must wait to be processed
  4. Speeds up request queue speeding up response times and avoiding 503 “Server Unavailable” errors
  5. Benefits requests that don’t perform lengthy I/O operations and can get in and out of the pipeline quickly

V.    Application Optimization

A      Optimize the frequent code paths

Following the 80/20 rule, 20% of an application’s code typically accounts for 80% of a project’s execution.   When reviewing a project it is important to focus on these frequent code paths, a few examples of potentially long running processes are

  1. Loops
  2. Use of outside resources (DB, I/O, etc)
  3. Type and string management
  4. When possible avoid late binding (use of Object type)
  5. Destroy objects as soon as you no longer need them
  6. Efficiently use Data binding

B       Visual Studio 2005 Code Analysis

Run the Code Analysis on the solution and fix any glaring problems.  Some warnings can be ignored, but many are important to address

C      Other Suggestions

  1. Set reasonable timeouts on SqlCommand objects, web pages, web services, etc
    1. Also, ensure a web page does not timeout before a web service or SqlCommand times out.
  2. Search for potential problem code
    1. Error Handling: On Error
    2. Data Access: ‘SELECT ‘, ‘UDPATE ‘, ‘DELETE ‘, or ‘INSERT ‘
    3. ASP.Net: Response.Write, HttpContext.Items
    4. State Management: Session, Shared (Static) Properties
    5. Miscellaneous: Int16
  3. Search for a few phrases that should exist in your code; if it does not exist ask why
    1. Error Handling: Catch, Throw, Exception
    2. Code/Resource Cleanup: Finally, Using, Dispose, Close, set to Nothing
    3. String Manipulation: StringBuilder, Format, AppendFormat
    4. ASP.Net: Cache
    5. State Management: Cache, Application
    6. Object Oriented: Interface, Abstract, Friend / Internal, Protected, Private

    For more information checkout: http://codebetter.com/blogs/karlseguin/archive/2006/05/18/144881.aspx

 
 

“Everything should be made as simple as possible, but not simpler”

-Albert Einstein

No Comments Yet »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.