Posts Tagged ‘ASP.NET MVC’

This week I came across a problem related to structuring an ASP.NET MVC Web application one development team was facing. What they were trying to do was quite simple: to create a folder structure each having their own subfolders for View/Controller/Scripts/CSS etc. The application resources like JS/CSS etc. were not getting rendered properly. The issue was due to Web.config file lying under the subfolder, which when moved to the Views folder under that subfolder things went fine. The purpose of this post is not to discuss about the details of that problem and it’s solution.But to discuss about how we can easily structure our ASP.NET MVC Web application as per different modules, which is an obvious need for any large application.

ASP.NET MVC follows the paradigm of “Convention Over Configuration” and default folder structure and naming conventions works fine for a smaller application. But for relatively bigger one there is a need to customize.The framework also provides enough provisions for the same.You can have your own controller factory to have custom ways to creating the controller classes and custom view engine for locating the rendering the views. But if the requirement is to structure the application to different subfolders as per modules or subsites  I think the use of “Area” in ASP.NET MVC will be helpful to create a streamlined application.

You can add an Area to a ASP.NET MVC project in VS as shown below.

area1

area2

Here I have added an area named “Sales”. As shown in the figure below a folder named “Areas” is created with a subfolder “Sales”. Under “Sales” we can see the following

  • The standard folder of Models/Views/Controllers
    • A Web.config under the Views folder. This contains the necessary entries for the RazorViewEngine to function properly
  • A class named SalesAreaRegistration.

area3

The code (auto generated) for the SalesAreaRegistration class is shown below:

public class SalesAreaRegistration : AreaRegistration 
{ 
    public override string AreaName 
    { 
        get 
        { 
            return "Sales"; 
        } 
    }

    public override void RegisterArea(AreaRegistrationContext context) 
    { 
        context.MapRoute( 
            "Sales_default", 
            "Sales/{controller}/{action}/{id}", 
            new { action = "Index", id = UrlParameter.Optional } 
        ); 
    } 
} 

System.Web.Mvc.AreaRegistration is the abstract base class use registering the areas into the ASP.NET MVC Web Application. The method void RegisterArea(AreaRegistrationContext context) needs to be overriden to register the area by providing the route mappings. The class System.Web.Mvc.AreaRegistrationContext encapsulates the necessary information (like Routes) required to register the area.

In Global.asax.cs Application_Start event we need to RegisterAllAreas() method as shown below:

AreaRegistration.RegisterAllAreas();  

The RegisterAllAreas method looks for all types deriving from AreaRegistration and invokes their RegisterArea method to register the Areas.

Now with the necessary infrastructure code in place I have added a HomeController and Index page for the “Sales” area as shown below.

 

area4

Now I am trying to run the application and got the following error: [NOTE: This has nothing to do with areas but because I have two controllers with same type name i.e. HomeController]

Multiple types were found that match the controller named ‘Home’. This can happen if the route that services this request (‘{controller}/{action}/{id}’) does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the ‘MapRoute’ method that takes a ‘namespaces’ parameter.

The request for ‘Home’ has found the following matching controllers:

AreasDemo.Controllers.HomeController

AreasDemo.Areas.Sales.Controllers.HomeController

I have to change the Route Registration for the HomeController to avoid conflicts and provide the namespace information as shown below:

public static void RegisterRoutes(RouteCollection routes) 
{ 
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute( 
                "Default", // Route name 
                "{controller}/{action}/{id}", // URL with parameters 
                new { controller = "Home", action = "Index", id = UrlParameter.Optional },// Parameter defaults 
                new String[] { "AreasDemo.Controllers" } 
            ); 
}

Now I will add a link to the Sales area by modifying the _Layout.cshtml as shown below:

 
<li>@Html.ActionLink("Sales", "Index", "Home", new { area="Sales"},null)</li>

Here I am navigating to the area “Sales” from the main application so I have to provide area information with routeValues. The following overload is being used in the code above:

public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes);

For navigating within the “Sales” area however routeValues will not be required.

Advertisements

In my last post I had completed the demo of building a layered ASP.NET MVC application(the bookmark list application).This week I thought of adding the StructureMap container to that demo.I am quite new to StructureMap but I loved it’s usage of Fluent Interfaces and DSL a lot.I have primarily applied what I understood from it’s online documentation.I wanted to keep the option of plugging in another container later in this application.So I defined my own container interface as shown below:

    public interface  IContainer {
       
void AddInstanceConfig<I, T>(string key) where T:I; //Configures an instance with instance key,type and concrete type
       
void StartContainer(); //Starts the Container
       
object GetInstance<I>(string instanceName); //Returns an object instance based on the instance key/name
       
void DestroyContainer(); //destroys the container and releases the references

(more…)

Building the ASP.NET MVC Application

In the last 2 posts we have seen how to develop the Repository and WCF Services for our sample ASP.NET MVC application.This application contains the following Views:

  • Home/Index (Index.aspx) – Displaying the list of Bookmarks with options to Add New,Edit and Delete.
  • Add New (Create.aspx) – Displaying a blank form to enter the URL and Description.
  • Edit (Edit.aspx) – Displaying URL and Description of the selected bookmark.Only Description is editable.

There is a controller BookmarkController for all the above mentioned views.
(more…)

Building the Service

In my last post I have explained step by step how we can implement the Repository pattern with ADO.NET Entity Framework.In this post we will see how to expose that functionality as a WCF service.But prior to that let us briefly touch upon the Service Interface pattern to get our concepts clear.While developing enterprise application most of the times we try to decouple the Business Logic components from the UI components so that the two can evolve and change independently of each other.Along with this the ability to scale out the application across multiple nodes is also another driver.This pattern addresses these forces and provides a solution where we expose our business functionality via a Web Service which can be accessed by multiple clients over the network using varied protocols.

Now we will see step by step how to develop the WCF based Service Interface for our Bookmark Repository.

(more…)

Building The Repository

In my last post I had discussed about the various O/R mapping patterns and Repository is one of them.In this post we will develop a repository library for our sample application.This application is a very list of personal bookmarks with an url and description.

Step1: Create the database table

The database contains a single table called Bookmarks as shown below:

CREATE TABLE [dbo].[Bookmarks](
    [BookmarkId] [int] IDENTITY(1,1) NOT NULL,
    [Url] [varchar](100) COLLATE Latin1_General_CI_AI NOT NULL,
    [Description] [text] COLLATE Latin1_General_CI_AI NOT NULL,
CONSTRAINT [PK_Bookmarks] PRIMARY KEY CLUSTERED
(
    [BookmarkId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

(more…)

Normally while developing ASP.NET applications we follow a layered architecture with the Web/Presentation layer decoupled from the core business logic via the Service Interface.Whereas most of the examples we come across in ASP.NET MVC, the Model (O/R layer) seems to be very tightly integrated with the web application.I just started how I can seperate out the O/R layer and expose it via a WCF service and make the ASP.NET MVC application talk to the this service only.While doing so I found out that to seperate the different components into individual layer it is extremely important to understand the underlying application design patterns, how and where they fit in.In this post I will discuss about the Object Relational Mapping patterns and how it can help us to isolate the O/R.The three object relational mapping patterns discussed in this post are from Martin Fowler’s Patterns of Enterprise Application Architecture.
(more…)