Archive for April, 2012

In the last post we have discussed at length about different mechanisms of parameter passing and obtaining results from a workflow.In this post we will discuss about another extremely important aspect of workflow and host communication i.e. Bookmarks. Bookmarks as the name suggests is a like Bookmark for a book. When created at a particular point in the execution of the workflow , the execution is suspended and the workflow waits to be resumed.When a bookmark is resumed it starts executing exactly from the same point.

(more…)

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.

Workflow host is an application responsible for executing the workflow and managing different workflow lifecycle events like start, completion, idle, unloaded etc.Now the workflow host should be capable of exchanging information with the workflow. This information exchange can be broadly categorized into:

a) The parameters/arguments needed to start the workflow and to get the results back after workflow has executed.

b) The intermediate data needs at different stages of a long running workflow (e.g. when the workflow is waiting for a specific input like Manager’s Approval).

In this post we will concentrate on the different mechanisms of parameter passing and getting results back. In the subsequent posts we will move into more complex scenarios related to long running workflows.

WF 4.0 provides two classes for hosting and managing the workflows System.Activities.WorkflowInvoker and System.Activities.WorkflowApplication.WorkflowInvoker provides a simple model to execute the workflow like a method call whereas WorkflowApplication much greater flexibility to execute and manage the workflow instance. To start with we will explore the different mechanisms to pass data back and forth using WorkflowInvoker and WorkflowApplication.

(more…)