CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeremy D. Miller -- The Shade Tree Developer

Under the hood and working with .Net, TDD, Software Design, and Agile Stuff

Test Driven Development with ASP.Net and the Model View Presenter Pattern

DISCLAIMER:  This was written all the way back in Feb. 2006 when we MVP with ASP.NET was the only real alternative.  I thank you for the interest, but there have been better articles written since, and I'd strongly recommend looking at MonoRail or Ruby on Rails or the new MVC framework for ASP.NET if you're interested in maintainable, testable web applications. 

 

A friend of mine was asking me a while back about ways to apply the Model View Presenter (the “Humble Dialog Box”) pattern to ASP.Net development to promote easier unit testing of the user interface layer.  Two weeks and a major case of writer’s block later, I finally finished the post.  I wrote a blog post last spring describing the usage of MVP (“The Humble Dialog Box”) with WinForms clients, but web development in general and ASP.Net in specific comes with a different set of challenges. 

 So what are the problems with ASP.Net that MVP Solves? 

If you asked me to name the single most important principle in all of software design, regardless of language, platform, or programming paradigm, I’d say “Separation of Concerns” in a heartbeat.  For the sake of maintainability, each piece of code should have one and only one distinct responsibility.  Even in the initial act of coding I only want to work on one problem at a time.  I want to look at the business logic code without seeing database infrastructure code or HTML construction intermingled with everything else (a huge pet peeve of mine). 

 

The traditional approach for building maintainable user interface code is to separate the typical concerns of a user interface with the Model View Controller (MVC) pattern.  Unfortunately, ASP.Net is optimized for Rapid Application Development, not for creating maintainable code.  A common criticism of the ASP.Net development model (and ASP classic before that) is that it does not enforce or even encourage a clean Model View Controller separation.  Many ASP.Net applications seem to be a jumble of data access code, HTML markup, and business logic, but it doesn’t have to be that way.  By itself, the “code-behind” model in ASP.Net does not do enough to create a good separation of concerns.  Plus it’s difficult to get code-behind code into unit tests. 

 

My preference is to use the Model View Presenter pattern to structure ASP.Net code to create maintainable and testable solutions.  I think of MVP as just a flavor of MVC, but it’s worth stating the differences.  The central fact of MVP architectures is that the “view” is a very shallow wrapper around the actual screen.  Unlike most traditional MVC implementations, the view classes are entirely passive.  The Presenter classes are the active classes that are responsible for initiating the view processing. 

 

The big challenge in unit testing ASP.Net code is the tight coupling to the ASP.Net runtime.  The web controls are very tightly bound to the underlying HttpContext and the web event pipeline, making the user interface code difficult to work with inside an xUnit test harness.  I’ve seen people successfully create fake HttpContext objects in memory, but it really amounts to a hack to test existing legacy ASP.Net code.  You can also use tools like NUnitASP or Selenium to test web applications, but those tests are integration tests, not unit tests.  The best thing to do in my experience is to isolate as much of the functionality as possible away from the ASP.Net runtime into classes that can be easily tested inside of NUnit, and that’s exactly what the MVP pattern does.  Putting this another way, I would suggest that any piece of code that isn’t directly manipulating web controls or parts of the web page should be moved out of the code behind classes and into another class.

 

A lot of .Net literature describes the “Code-Behind” class as the MVC controller.  I think this is dead wrong.  The code-behind is View code, period.  For best results, the presenter should never have any reference to any type in the System.Web namespace. 

 Class Structure of MVP 

The basic concept is simple.  Like the classic Model View Controller pattern, you divide the responsibilities of the web page into separate classes.  In specific, we want to isolate as much of the functionality as possible away from the ASP.Net runtimes.  The functionality of a screen is divided into three parts:

 
  • View classes:  Displays data and relays user input and events to the Presenter. 
  • Presenter classes:  Coordinates communication between the view and the backend service or business layer and is responsible for user interface logic
  • Model classes:  The data being displayed or worked on in the screen.  This is could be either a business domain object(s), a data transfer object, or a lowly DataSet.  The Model is also the state of the user session. 
 A Simple Example 

Let’s dive into some code.  You’re creating a new web screen in a custom workflow application for people to enter and assign “WorkItem’s” to other people.  The screen will have dropdown lists for both the WorkItem category and the assigned user.  In no particular order, let’s start with the Model class.

       public class WorkItem      {            private string _category;            private string _assignedTo;             public string Category            {                  get { return _category; }                  set { _category = value; }            }             public string AssignedTo            {                  get { return _assignedTo; }                  set { _assignedTo = value; }            }             /* Other stuff */      } 

The next step is to create an abstracted interface to represent the View class.  Note that we’re not yet working with any System.Web classes, web pages, or web controls.  The IWorkItemView interface encapsulates all interaction with the ASP.Net runtime.

       // Abstracted interface of the WorkItem View screen      public interface IWorkItemView      {            // Packs the user input into a new WorkItem class            WorkItem WorkItem{get;}             // Sets the values in the dropdown list for the WorkItem assigned to user            string[] AssignmentList {set;}             // Sets the values in the dropdown list for the WorkItem categories            string[] CategoryList {set;}      } 

The backend business and workflow system is accessed by a Façade class with an interface called IWorkItemService.  The backend might be a call to a web service, a remoted object, or an in-process call.  All we’re concerned with in the user interface code is how the presenter interacts with the interface of the service. 

       public interface IWorkItemService      {            void ProcessWorkItem(WorkItem entry);            string[] GetAssignmentListForCategory(string category);            string[] GetCategoriesForRoles(string[] roles);      }  

The lynchpin of the MVP pattern is the Presenter class, WorkItemPresenter.  In this particular user story there is a requirement that the categories displayed in the dropdown on the screen are limited by the role membership of the logged in user.  There is another requirement that the values in the dropdown for the assigned to user are dependent upon the selected category.  The logic that determines the topic and category list is completely isolated from the web page machinery for easier unit testing and maintainability.

             public class WorkItemPresenter      {            private readonly IWorkItemView _view;            private readonly IWorkItemService _service;             // Use "Dependency Injection" to attach the dependencies for the view            // and service.            public WorkItemPresenter(IWorkItemView view, IWorkItemService service)            {                  _view = view;                  _service = service;            }             public void Initialize()            {                  string[] categoryList = this.determineCategoryListFromUserRoles();                  _view.CategoryList = categoryList;            }             public void Submit()            {                  WorkItem item = _view.WorkItem;                  _service.ProcessWorkItem(item);            }             public void ChangeCategory(string categoryName)            {                  string[] assignmentList = _service.GetAssignmentListForCategory(categoryName);                  _view.AssignmentList = assignmentList;            }             public string[] determineCategoryListFromUserRoles()            {                  // Examine the roles on the IPrincipal object and query IWorkItemService for                    // the possible categories                   return new string[0];            }

      }

 

The key things to note here are that the WorkItemPresenter class only depends on the abstracted interfaces for IWorkItemView and IWorkItemService.  The WorkItemPresenter class can now be unit tested with mock objects inside of the NUnit.  WorkItemPresenter is just a “Plain Old CLR Object” that can run and be tested completely outside of the ASP.Net process.  This is strictly personal preference, but I like to build and unit test the Presenter class(es) before I even start to create the ASPX or ASCX’s. 

        [TestFixture]      public class WorkItemPresenterTester      {            private DynamicMock _serviceMock;            private DynamicMock _viewMock;            private WorkItemPresenter _presenter;              [SetUp]            public void SetUp()            {                  _serviceMock = new DynamicMock(typeof(IWorkItemService));                  _viewMock = new DynamicMock(typeof(IWorkItemView));                   _presenter = new WorkItemPresenter((IWorkItemView)_viewMock.MockInstance, (IWorkItemService)_serviceMock.MockInstance);            }

      }

 

Lastly, we’ve got to actually create the web page itself.  I’m using a UserControl as an example, but it could easily be a web page instead.  The WorkItemView UserControl implements the IWorkItemView interface.  It has a reference to an instance of the WorkItemPresenter class with which it communicates.

       public class WorkEntryView : UserControl, IWorkItemView      {            private WorkItemPresenter _presenter;            protected DropDownList assignmentDropdown;            protected DropDownList categoryDropdown;             // The UserControl has a reference to the presenter class            public void AttachPresenter(WorkItemPresenter presenter)            {                  _presenter = presenter;            }             private void Page_Load(object sender, EventArgs e)            {                  categoryDropdown.SelectedIndexChanged += new EventHandler(categoryDropdown_SelectedIndexChanged);            }             #region Web Form Designer generated code             public WorkItem WorkItem {…}              /// <summary>            /// Fill the dropdown list for the possible assignments            /// </summary>            public string[] AssignmentList            {                  set                  {                        assignmentDropdown.Items.Clear();                        foreach (string assignment in value)                        {                              assignmentDropdown.Items.Add(assignment);                        }                  }            }             public string[] CategoryList{…}              // The UserControl immediately relays the user selecting a new Category to the             // presenter object.  The presenter will decide what to do next            private void categoryDropdown_SelectedIndexChanged(object sender, EventArgs e)            {                  string category = categoryDropdown.SelectedValue;                  _presenter.ChangeCategory(category);            }

      }

 

In this case I have an ASPX page that contains a WorkItemView control.  In the Page_Load event of the ASPX page I create a new instance of the WorkItemPresenter, attach it to the user control, and call Initialize() on the presenter class to start the display.

       public class WorkItemPage : System.Web.UI.Page      {            protected WorkEntryView workEntryControl;             private void Page_Load(object sender, System.EventArgs e)            {                  WorkItemPresenter presenter = new WorkItemPresenter(workEntryControl);                  workEntryControl.AttachPresenter(presenter);                   presenter.Initialize();            }

      }

 State Management 

A big challenge in any complex web application is session state.  Think of a typical online store like Amazon.  On one hand the logic involved in maintaining the session state is important and certainly deserving of isolated unit tests.  If I was coding for Amazon, I would certainly want to be writing unit tests around maintaining the state of the “shopping cart” when users select and remove items.  The state of the shopping cart will affect the way the page is displayed and the navigation logic after the page.  That’s exactly the kind of logic that is hard to test if you don’t loosely couple the logic from the HttpContext. 

 

On the other hand, a lot of web screens are only reachable from a series of user actions on previous pages.  The checkout screen can only be reached after working through previous screens.  My first TDD project was an ASP.Net project that had some web pages like this.  We were using NUnitASP to write automated tests.  I didn’t know much about mock objects or MVP (or MVC), so the only way to test my pages and all of their logic was to write tests that progressed through multiple screens just to get to the point where I really wanted to test.  Those tests were laborious to write and very brittle.  Smaller tests are always easier to write and read.  What I’ve learned since then is to either create an abstraction around the state management that the presenter classes depend on, or have another class push the state into the presenter.  I touched on this strategy in an earlier post on mock objects.

 

At some point you do have to test the actual web screens, and it’s a great thing to have automated testing on the user interfaces.  It’s just a theory, but I’d think seriously about creating intermediate integration tests that use stubs for all the backend and state management to isolate the web views.  You can use a dynamic service locator like StructureMap to substitute stubs for the services with configuration, or create separate ASPX pages to host the UserControl’s and presenter classes, but use the stub objects instead.  You could then write much simpler Selenium tests to verify granular parts of the user interface in isolation.  You’ve got to maintain loose coupling between the user interface code and the backend to pull it off though.  As usual, testability and good design practices are very closely aligned.

 User Input Validation 

I’ve had a couple of conversations over the last year on the proper place for the user input validation.  I still think you have to take advantage of the built in validation controls in the ASP.Net views if you can do it in a declarative way.  Any kind of validation more complicated than “this field is required” or numeric validation should probably be put into some sort of presenter class or the model classes.   By and large, you want any kind of code that spawns bugs under automated unit testing.  Input validation definitely meets that criterion. 

 

Something I like to do is use what I think of as “Embedded Controllers.”  You need to be cautious in using the MVP pattern to keep the presenter classes from getting too big with too many responsibilities and preventing the bidirectional view-presenter communication from being way too chatty.  I try to alleviate the presenter “blob” anti-pattern by moving validation logic into other controller classes that are used from within the views.  I also like to move functionality like filtering, paging, and sorting to these secondary controller classes.  It’s just a way of keeping the size of the classes down and maintaining class cohesion. 

 Easier NFit/FitNesse Testing 

We’ve had some success with writing our FitNesse tests directly against the Presenter classes.  We have been making the Fixture class for the screen implement the interface for the view and passing itself into an instance of the Presenter, then letting an ActionFixture drive the screen.  It’s a lot simpler than trying to drive the tests against the screens themselves.  Our sister office is using FitNesse to drive Selenium tests to great effect, but they’re doing it because they don’t have a suitable service layer to test business logic through.  These Fixtures look something like this:

 using System;using fit; namespace WebSample{      public class DataEntryFixture : Fixture, IWorkItemView      {            private string[] _assignments;            private string[] _categories;            private WorkItemPresenter _presenter;             public DataEntryFixture()            {                  _presenter = new WorkItemPresenter(this, new WorkItemService());            }             public WorkItem WorkItem            {                  get { throw new NotImplementedException(); }            }              public string[] AssignmentList            {                  set { _assignments = value; }            }             public string[] CategoryList            {                  set { _categories = value; }            }             public string SelectedCategory            {                  set                  {                        _presenter.ChangeCategory(value);                  }            }      }

}

   Related Concepts 


Comments

Sam said:

>> "The code-behind is View code, period."

Amen. EXCELLENT post.
# February 2, 2006 12:13 AM

Liang said:

Excellent! Excellent!!
I definitely need to look at StructureMap to find out how to set up stub. I am using MVP in my projects. But I still haven't found a goog way to test ASP.NET page. By the way, we should do our validation on presenter or domain layer as well as on presentation layer, since presenter or domain can be used for WinForm as well. so that they have to encapsulate their own logic.
# February 2, 2006 12:40 AM

cs said:

"A lot of .Net literature describes the “Code-Behind” class as the MVC controller. I think this is dead wrong. The code-behind is View code, period."

I keep telling people that ASP.Net's MVC claims are mostly junk. You're posts are always awesome. Where do you work anyway? Sounds like an awesome place.
# February 2, 2006 2:48 AM

Co Kierepka czyta, wie lub myśli, że wie :) said:

Doskonały artykuł o tym jak stosować MVP (Model Viewer Presenter) w ASP.NET

&#160;

Test Driven Development...
# February 2, 2006 3:39 AM

Harris said:

Jeremy,

Great post!! I really like how you incorporated the presenter into UserControls.

One comment I have is related to the interface of the view. A collegue of mine didn't like the fact that by "exposing" the Model thru the View (i.e., your WorkItem { get; } property), your no longer decoupling the view from the model; or, otherwise put, the UI now knows about the model and if the the UI isn't supposed to know intimate, inner workings/knowledge of the model. I tend to agree with him, but it leads to coarser View interfaces unfortunately...I guess it's all a balancing act...

Great post, again, regardless.

H
# February 2, 2006 2:58 PM

Michael said:

Jeremy, that was fantasic. I've been looking for great MVP examples recently, and that hit the mark.

A somewhat related question...

Let's say I have in coding the Presenter, I've created an interface to a back-end service and mocked it, such as you have with the WorkItemService. During this process, the code in the Presenter has come to shpae not only the interface of the service, but the behavior as well, such as expected return values, exceptions, parameter handling, etc.

Now when it comes time to develop the real implementation of the service interface, there's always the chance that you don't exacly recreate the behaviors the Presenter depended on. Maybe you throw throw the wrong exception, or return an empty list in cases where the Presenter was coded against the expectation of null, or some other such quirk.

How do you either resolve or avoid this?

Another problem (I'll just throw stuff out there... comment, blog about it, ignore it... ;) is dependencies. Do you ever find that excessive constructor dependencies becomes a problem in cases where the Presenter takes a service, and the service takes a data gateway, and the gateway takes a session manager, and the session manager takes a cache manager, etc. That's just a contrived example, but you get the idea. Essentially, because the dependencies must be injected for the benefit of TDD, you're now faced with top-level objects having to build a cache manager to build a session manager to build a gateway to build a service, when all it really cares about is the service interface. Do you just ignore it and rely on DI container config files to do it for you, or are there other techniques, or am I missing something and this never happens?

Anyway, thanks for everything, and keep blogging!

Michael
# February 2, 2006 9:22 PM

dudu said:

# February 6, 2006 2:21 AM

Jeremy D. Miller said:

Harris & Michael,

I'll put out a followup post in the next couple of days to address both questions/objections

Jeremy
# February 6, 2006 12:36 PM

Carlton said:

I know this is old, but I just had the time to print this up and read it - I like this article.

One quick question: isn't the Presenter in MVP just an expression, or a usage, of a Mediator pattern from GOF? Not that I am knocking your article or MVP, just want to clarify my own understanding. Thank you.
# February 10, 2006 12:44 PM

matt d said:

For unit testing your asp.net apps you might check out RUnit:

http://www.ruxp.net/runit.asp

it allows you to run your NUnit tests under the asp.net process.
# February 13, 2006 12:25 PM

Jeremy D. Miller -- The Shade Tree Developer said:

This is a follow up to my post on the Model View Presenter pattern with ASP.Net to address or clarify...
# February 16, 2006 1:18 AM

Jeremy D. Miller -- The Shade Tree Developer said:

Author: &lt;a href=&quot;blogs/jeremy.miller&quot;&gt;Jeremy D. Miller&lt;/a&gt;&lt;br /&gt;Carlton commented that the Presenter class looks a lot like the Gang of Four &quot;Mediator&quot; pattern. He's absolutely right. Something to keep in mind when learning to apply design patterns is that a class or group of classes can easily be an instance of more than one pattern. In this case &quot;Presenter&quot; or &quot;Controller&quot; is just a more specific name for a class within a larger structural pattern.
# February 16, 2006 9:21 AM

Forward Observation Post said:

# February 17, 2006 12:08 PM

Alex said:

Look at SWExplorerAutomation
(http://home.comcast.net/~furmana/SWIEAutomation.htm). The program creates automation API for any Web application based on HTML and DHTML The API is used to visually record the test scripts.

Example links:

1) Testing your web UI using SWExplorerAutomation and
NUnit:http://www.testingreflections.com/node/view/2763

2)Automating Web UI testing with SWEA, C#, & NUnit (part
http://qainsight.net/PermaLink,guid,de5297ad-53de-4a9d-a78f-bb580afefb5b.aspx
# March 5, 2006 3:05 PM

Jeremy D. Miller -- The Shade Tree Developer said:

This past Saturday was the Austin Code Camp.&amp;nbsp; I had a great time and the general consensus was that...
# March 6, 2006 8:32 AM

David Hayden [MVP C#] said:

Jason Haley points to a&amp;nbsp;really nice introduction to using NHibernate with ASP.NET, called NHibernate...
# March 12, 2006 10:39 AM

Billy McCafferty said:

# March 15, 2006 10:10 PM

Billy McCafferty said:

# March 30, 2006 6:59 PM

Billy McCafferty said:

# March 30, 2006 7:04 PM

Amy Baker said:


Questions:
1. How does MVP handle validation when using the built in .Net validators? Custom validators? Is the presenter involved in that at all or does the view take care of everything? It would be nice to have the validation be testable through the presenter, but it may have to be done through the View.

2. General question: How to build up text in the presenter to give to the view if the text varies along many different concepts. Example: Simple heading text. We have an inordinate amount of variation in the text for a heading. There are 4 words in our heading. What to display for each word varies on a different concept. You could either have a lot of if statements in your presenter, or have your presenter contain strategies for each different concept and build up the heading that way. Using the strategies seems like better OO design, but almost seems overkill and seems like it would be hard to maintain. Any suggestions?

3. How do you handle variations in layout? If one layout has three columns, 4 rows and another has 2 colums, 3 rows, do you make a second ascx and code behind even though 90% of the layout is the same? Or does the presenter set a LayoutState on the view and the view then writes out the appropriate html from the code behind based on that LayoutState? I don't like making a second view that has so much duplication, but I also don't like writing out html from the code behind. Any ideas?
# June 1, 2006 3:06 PM

Jeremy D. Miller -- The Shade Tree Developer said:

If you're in Austin, I'm doing a presentation on StructureMap at the ADNUG meeting on July 10th.
Mea...
# June 29, 2006 7:02 PM

mk said:

some people pull their code out of their asses , if you want to be smart
make sure your code compiles first. If not you're not differnet than M$ developers.

--constructor, class WorkItemPresenter
public WorkItemPresenter(IWorkItemView view, IWorkItemService service)

--class WorkItemPage
WorkItemPresenter presenter = new WorkItemPresenter(workEntryControl);


# August 6, 2006 7:38 PM

Jeremy D. Miller said:

Um, MK -

Can you say "contrived example?"  I cut it out of the example in the page for brevity, but I simply used a second constructor that only takes in an IWorkItemView and constructs the default instance of the IWorkItemService.

# August 6, 2006 9:11 PM

Community Blogs said:

Martin Fowler recently split the Model-View-Presenter pattern into two new patterns, Supervising Controller
# August 9, 2006 4:06 AM

Bob.Yexley.Net said:

Phil Haack wrote a great article on his blog yesterday demonstrating in detail how to implement the Model
# August 9, 2006 5:19 PM

Don Cameron said:

Jeremey, nice work.

It is working well, but I am having a bit of conceptual struggle implementing the User Interface Application Block with MVP.  The UIP maintains state in the controller, and has a single controller per business thread, or business group.  Any work done in this area?

Don

P.S.  As for MK:  I would like to see critics like this post their work on the net for all to see.  I really detest people who pick at little wrong things in light of all this good.

# January 24, 2007 10:57 AM

Jeremy D. Miller said:

Don,

As far as I know, the UIP is effectively dead.

Jeremy

# January 24, 2007 11:39 AM

Jeremy D. Miller -- The Shade Tree Developer said:

Jay Kimble , CodeBetter's resident AJAX guru, issued a little challenge to us TDD bloggers about using

# March 7, 2007 2:05 PM

Polymorphic Podcast said:

Design Patterns Bootcamp: Model View * Patterns Listen to the Show! Thanks to Dave Bost for the intro!

# March 8, 2007 10:15 AM

Craig Shoemaker said:

Design Patterns Bootcamp: Model View * Patterns Listen to the Show! Thanks to Dave Bost for the intro!...

# March 8, 2007 10:18 AM

Console.Write(this.Opinion) said:

Outro dia respondi uma pergunta no fórum MSDN sobre desenvolvimento em camadas. Meu único conselho para

# March 18, 2007 1:50 PM

' + title + ' - ' + basename(imgurl) + '(' + w + 'x' + h +') said:

Pingback from  ' + title + ' - ' + basename(imgurl) + '(' + w + 'x' + h +')

# June 20, 2007 3:23 PM

思无邪 said:

# July 17, 2007 7:27 AM

Daryn said:

MVP is a wonderful design pattern.

Thanks for this great post.

I have the following questions:

How can you use the MVP when creating a wizard type interface?

I want the user to be able to click ‘next’ then the current triad changes to the next triad, and updates the view.   I have an implementation, but it does not seem that ‘clean’.

1. So how do you change triads/views?

In MVC a model could have multiple views.   As far as my understanding of MVP, each presenter has no more than one view – a model can have multiple presenters.

2. Are these thoughts correct?

Thank you!

# July 20, 2007 5:27 AM

Imran Ahmedc said:

Dear Manager,  

Hope you are doing great!

The purpose of this letter is to introduce you to CAT Technology Inc and our Offshore Development services. We are the leading Offshore Development service company in INDIA. We align ourselves with our customers as partners to assist them in achieving their goals and objectives. We would be delighted to demonstrate our offshore Development services to you. Please let me know if you have any software Development work to Outsource?

Out Team size in INDIA:

.Net/C# Developers: 90 Members

Delphi Programmers: 18  Members

Web developers: 50  Members

JSP/ Java Programmers: 45 Members

PHP Programmers: 30 Members

System/Network Administrators (MCSE) (CCNA) (CCNP):30 Members

Visit us at--- www.cattechnologies.com

View our development office in INDIA :

You can view our development office in INDIA through this camera.

Camera Server URL: http://203.197.241.56

Login: cat

Password: techno

Dedicated Staff:

When you set up an offshore development center with CAT, you get the following:

All hardware, software licensing and office infrastructure already in place A dedicated team of professionals who will learn your business and become a part of your team. Seamless collaboration between offshore office and client project staff through live chat / email / voice / video .U.S. based contact point to manage all issues throughout the relationship and insure success of all projects. All staff assigned to your team will report directly to you or your project manager and follow your directives and timelines.

Maintenance Projects:

Just because your project is complete does not mean you don’t need professional technical support for your existing applications.  Our staff are available to you on a dedicated basis to review your existing applications and provide you the support and technical updates that are needed to maintain the competitiveness of your applications. If you are a new customer to CAT, ask us about our maintenance plans that enable you to take care of your application beyond the major development phase.  Maintenance Services are available to your regardless where you had your application developed

Project Based:

Are you looking for professionals to help you build your projects?  If so, consider CAT as your world class partner. We will work closely with you to understand your project's requirements, deadlines, technologies and needs to determine the best team to make your project a success. Also, you can decide whether you plan to manage the project internally and utilize our development and testing resources, or prefer to have one of our project managers lead the team.

Wide range of PHP Services we provide:

1.  PHP Programming

2.  Database development (php/mysql,)

3.  MYSQL PHP Programming, script installing, modification, and PHP Script repairs.

4.  Custom web site design/redesign and development

5.  Custom PHP and MYSQL web programming

6.  PHP shopping cart

7.  PHP forum

8.  PHP content management system

Wide range of .Net Services we provide:

1.  Application Development using .NET

2.  Designing and Programming using .NET

3.  Migration web based and other applications to .NET

4.  Porting of Legacy applications to .NET based applications

5.  Support and Enhancement of existing applications in .NET

6.  User needs assessment / functional spec writing

7.  Website architecture design

8.  User Interface design

9.  Graphic artwork development with Photoshop & ImageReady

10. Database design

11. Stored procedure development

12. OO Design and development of middle tier objects

13. ASP.Net development with C# or VB.Net

14. .Net desktop application development

15. JavaScript development & cross browser issues

16. Ajax/Atlas Development

17. IIS setup & security issues

18. Website hosting

19. E-Commerce development

20. Conversion of legacy system data

21. Web Marketing / Search Engine Optimization / SEM

22. Software Testing & QA

23. Web based report development

24. Adobe PDF file generation

25. Integration with existing systems

Wide range of Web Development Services we provide:

We have designed websites of various styles, sizes and purposes. We have a team of 50 Web designers and Developers in our office in INDIA.

1.  Custom Website Design

2.  Template Website Design

3.  Custom E-commerce Design

4.  Website Re-Design

5.  Macromedia Flash Design

6.  Graphic Design

Wide range of Network Support / System Administration Services we provide:

1.  Onsite server support (upgrades, security patches, migrations)

2.  Remote management and administration

3.  Configure and maintain Windows 2000, 2003 servers and services (Active Directory, DHCP, DNS, IIS, RAS, NAT, VPN )

4.  Install, configure and Maintain Microsoft ISA 2004 server

5.  Installing & Administrating, Managing of Domain Controllers.

6.  Installing, Configuring & Administering the following

7.  Microsoft Exchange Servers

8.  Securing your Linux Server with Firewall / Troubleshooting your Linux System

9.  Server installation and configuration

10. Security analysis and policy development

11. Firewall firmware upgrades/Firewall policy implementation and management

12. LAN Administration

13. Microsoft Certified Systems Engineers (MCSE)

14. Cisco Certified Network Associate ( CCNA ) ( CCNP)

15. Network Installation

16. Network Management

17. Network Security and quality monitoring

18. Network Maintenance

19. Security Firewalls

Wide range of Java Services we provide:

1.  Web Application Development in Java

2.  Systems Programming in C, C++, VC++, C-Sharp (C#) and Java

3.  Web Hosting services in JSP and Servlets