Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Why(s) and How(s) of ASP.NET MVC: Part 2

0.00/5 (No votes)
26 Jul 2013 1  
ASP.NET MVC model binding approaches, fundamental ideas, advantages, and validating models.

Introduction

I know it's been a while since I wrote part 1. You have probably read lots of resources about ASP.NET MVC by now. Thus for now I will skip the how to do part and concentrate more on why. Also as we go along this series, I will demonstrate some exciting new features that are available to ASP.NET MVC. Please remember wherever in this post I mention MVC, it refers to MVC 4. In this post, we will will limit our discussion to Model. Why model is used, what approach to take while working with models, and validating them.

MVC on ASP.NET  

Sounds a bit old and an out of scope topic, but even now I see lots of discussion on how web form developers are planning to migrate to MVC. It's been a hot topic, hence I like to share some insights in this regard. For new developers MVC is a charmer, but for those who are considering to migrate from webform to MVC, the primary concern is familiarity with features that they are used to over the years. Most of webform developers' concerns is the ASP.NET webform framework has a lot to offer in the context of:

  1. Security 
  2. Debugging 
  3. Validations 
  4. State management 
  5. MasterPage/UserControl 
  6. RAD Controls 
  7. Familiar syntax 

Now the common question is does ASP.NET MVC fulfill these needs? Does it?

Humm, let's look at what ASP.NET MVC has to offer. Even though their architectural approaches are quite different, ASP.NET MVC and Web Forms actually have a lot in common.

Concerns ASP.NET MVC Web Form
Security Forms/Windows Authentication, MemberShip Forms/Windows Authentication, MemberShip
Validation Data Annotations Server Controls for validation
State Management Session and profile state View State/Cookies/Query Strings
Cross Page Data Transfer controller to view/controller to request ViewData, ViewBag, and TempData Session/Query String
Health monitoring Health monitoring Health monitoring
Caching output and data caching output and data caching
Master Page Layout Page Master Page
UserControl Partial View UserControl
RAD Control HTML helper Server Controls
Syntax Razor View Engines ASPX View Engines

Bingo, as you can see a Web Forms developer looking to learn ASP.NET MVC already is further ahead than he thinks. Productivity wise, ASP.NET web forms and MVC do not differ much, we can obviously raise the issue of RAD controls. I agree RAD controls speed up development but think how UX designers can play with views without the developer's involvement. Developers do not have to give their effort to implement cool UX utilizing RAD controls. Combining these final development efforts, the difference is very thin between webforms and MVC. Moreover there are a lot of good frameworks like angularJs/backbone js available these days to ease development effort. Productivity is the one of the major concerns for developers who wish to move from web forms to mvc.

This is no surprise like Web Forms, ASP.NET MVC is built on top of the ASP.NET platform. So both frameworks rely on .NET languages C# and Visual Basic .NET to interact with the .NET Framework, and can access compiled assemblies developed with any other language that the .NET Framework supports. Even interesting is while developing with MVC you will see the very familiar web.config and Global.asax. If you Google, you will probably get thousands of resources on these comparisons.

Working with Model

Now you can ask the obvious question, DB, Model or Code first? What are all these and how are they related to MVC? Fair enough, but to answer that let's step a back for a while to Part 1 which discusses the model part of MVC. Let's refresh our memory:

Models are those parts of the MVC application that play with the application's data domain and retrieve/store model state in a database.

So model is the heart of your application (from a business perspective) that deals with the single most important element: "data". Model represents your data structure and will contain functions that will help you to do CRUD (Create/Retrieve/Update/Delete) operations. Now depending upon the architecture, application type/scope, risk analysis, we need different approaches to implement the model entity. This is where EF (Entity Framework) comes in play. With EF we have the flexibility to work with models as we want to.

Entity Framework provides three ways to define the model of your entities. Using the database first workflow, with the model first workflow, and last but not least, code first approach. Code first approach of designing the model is becoming a popular choice due to complete control over the classes being written or implemented. But that doesn't mean DB first or model first are not cool to be used. The trick is to know when to use what, if you can analyze your application scenario/scope/risks and choose the one prefect for your scenario, in my opinion that is cool. Let's dive into our main topics.

Why Database First

Consider a scenario where an existing enterprise database tends to have many tables, each with many columns. They are not normalized as you prefer but can't complain as it's an existing database. No one will allow you to break and restructure the DB when there is a business in stack. In this situation the entity model of your application must be compatible to the existing database; you can’t bend the database to suit your preferred object model, in other words your hands are tied. Database First is popular in a scenario like this, also called a “brown field” scenario, with developers who build applications that access existing production databases holding large numbers of tables and columns.

When to adopt DB first approach is a different opinion over forums, groups, user meet-ups. Without reinventing the wheel I like to summarize those and here is the list; Legacy systems built upon existing DBs designed by DBAs, developed separately, or if you have an existing DB. 

  1. You will let EF create entities for you and after modification of mapping, you will generate POCO entities.
  2. If you want additional features in POCO entities, you must either T4 modify template or use partial classes.  
  3. Database defines your domain model. 
  4. A fair amount of business logic resides in the database end for better maintainability.

Now the question is, is it bad to use DB first? Many experts have their own view, my opinion is despite the non-comforting object model if the application is serving as it is supposed to be, then there is no reason to be unhappy about it. Every approach we are discussing here has its own pros and cons.

Advantages

  1. RAD development approach, EF will include all the usual metadata of the existing database, CSDL, SSDL, and the mapping between them just as model-first does. 
  2. Can concentrate on DB design first in case of dealing with big volume of data.
  3. Database is not just a storage, can utilize it to implement business logic also.

Disadvantages

  1. No control over EF generated code. 
  2. EF generated code is too complicated to customize.
  3. Less control over the EF generated entities.
  4. Imposing custom Entity level validation will require expertise on T4 template

Why Model First

Though DB first approach was the successor, changed development scenarios demanded Domain Driven Development, and model first brings the essence of DDD but not truly. Model first design came into prevalence where the Database Schema was based upon the Model. Though conceptually database and model first approaches are different, from an implementation perspective there in not much difference. Both end up with generating lots of auto generated code.

Just like in DB first, when to adopt this approach has varied answers, and my summarized version is,

  1. IMHO popular if you are designer fan (= you don't like writing code or SQL). 
  2. You will "draw" your model and let the workflow generate your database script and T4 template generate your POCO entities. You will lose part of control on both your entities and database but for small easy projects you will be very productive. 
  3. If you want additional features in POCO entities you must either T4 modify template or use partial classes. 
  4. Manual changes to database will most probably be lost because your model defines the database. This works better if you have database generation power pack installed. It will allow you to update the database schema (instead of recreating) or update database projects in VS. 

Advantages

  1. Database is not just a storage, can utilize to implement business logic also.
  2. Flexibility of creating entities that make sense in your business domain and their relationships.
  3. Minimize the "ripple" effect caused by changes in the object model (code) generated or the database.

Disadvantage

  1. The contents of the database will be generated each time, causing data loss as it regenerates everything every time you create the database from the model.  
  2. Once the database schema is published database can be changed directly in many occasions and thus the model becomes out of date and must be updated from the database in a database-first style.

Why Code First

In the Code First approach, you avoid working with the Visual Model Designer (EDMX) completely. You write your POCO classes first and then create the database from these POCO classes. This is an ideal candidate for Domain-Driven Design (DDD). Code First uses classes and properties to identify tables and columns, respectively. Code First has a number of benefits. First, developers are no longer delayed by not having a database. You can now create the database structure and start coding, with everything maintained in the same solution. Second, there's no auto-generated code; a developer has full control of each of the classes. Lastly, everything is kept simple in the data access layer because there's no .EDMX model to update or maintain.

Advantages 

  1. Can integrate model validation easily. 
  2. EF modeling often has weird errors, such as when you try to rename an association property, it needs to match the underlying meta-data - very inflexible. 
  3. Contrast back to Code First and you have complete control without all the hidden complexities and unknowns to deal with. 
  4. Enable migrations can keep track of schema changes, so can seamlessly deploy upgrades/downgrades while model changes.

I am a fan of Code First so I guess my opinion on disadvantages is biased.

Disadvantage

  1. No visual model designer (EDMX) support.
  2. No auto generated code.
  3. Manual changes to database will most probably be lost because your code defines the database.

There is no hard and fast rule on when to use Code First, but in general you can use Code First because,

  1. Full control over the code (no auto generated code which is hard to modify).
  2. Ideal for applications with complex business needs.
  3. Very popular because hardcore programmers don't like designers, and defining mapping in EDMX XML is too complex.  
  4. If you are expecting that the role of the database in your application is only storage. EF will handle creation and you don't want to know how it does the job.

Model Validation 

As we discussed in the above three approaches, model objects deal with data and perform business logic on that data. Models are application specific and hence the ASP.NET framework imposes no restrictions on the construction of model objects. But we can impose custom validation on models. The most common and convenient approach to add such validation is Code First because this approach ensures complete control over the model and two popular methods of validation are DataAnnotation and FluentValidation. DataAnnotation and FluentValidation both serve a similar purpose. They ensure that the values that have been assigned to the object properties satisfy the business rules that are supposed to be applied.

DataAnnotation FluentValidation  
Validation support built into the .NET Framework and can integrate with minimal code. Advanced validation support that is not possible with data annotations.
Not intended to work with DB/Model First, but with some workaround (buddy class) support. Supports only Code First approach.

Does that mean Database First or Model First approach does not need any model validation? While using the Database First or Model First, the EDMX file has the same purpose - it contains all the details and mapping definitions of your model. Whatever restriction (or constraint) you define, your database/database model is translated by EDMX mapping definitions, so you do not have to put extra effort to define your own. Fluent API or data annotations and conventions replace the EDMX file only when using Code-First.

Testing Models

One of the major focus of mvc is always been testing. Thus this post is incomplete to with out discussing a bit how to conduct unit testing on models. Just a heads up I will try to show positive and negative testing both. Hope to do discuss in details future.For example purpose lets take a very simple class with DataAnnotation, and only do the property set ruls testing. FYI, many experts recommends to test properties that are derived instead of testing each properties. 

public class User
{
    public string FName { private get; set; }

    public string LName { private get; set; }

    [Required]
    [StringLength(10)]
    public string Name { get { return string.Format("{0} {1}", this.FName, this.LName); } }

}  

Now, finally for the testing, for the sack of simplicity I am just going to test the Name rule, I have written two tests. one positive and one negative .
Positive test: is to make sure name length satisfy allowed length

    [TestMethod]
    public void Name_Should_have_valid_length()
    {
        User _userToTest = new User( );
        _userToTest.LName = "Sh."; //3 character
        _userToTest.FName = "Iqbal"; //5 character
        Assert.IsTrue(_userToTest.Name.Length <= 10);

    } 
Negative test: is to make sure throw error when name exceeds the allowed length
    [TestMethod]
    public void Name_Should_Fail_for_invalid_length()
    {
        User _userToTest = new User();
        _userToTest.LName = "Shahriar"; //8 character
        _userToTest.FName = "Iqbal"; //5 character
        Assert.IsTrue(_userToTest.Name.Length <= 10);

    }
For effective testing both - Positive and Negative testing should be utilized. I know the example is very small and basic but good for beginners, and hope to show more details testing techniques in upcoming posts.

References and Good Reads

Series 

  1. Why(s) and How(s) of ASP.NET MVC Part 1 - MVC Basics.

History

  • Version 1.0.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here