Thursday, June 17, 2010

MVCContrib – Portable Areas – Part 2 – Messaging

Update: After seeing a post on StackOverflow.com I have updated my sample code to work with the latest MvcContrib available through NuGet that supports MVC 2.

This is part two in a multi part series, the first entry is MVCContrib - Portable Areas - Part 1 - The Basics.  In that post we discussed how to setup and write a web site using a portable area (PA) that ran a Bing search.  In this entry we will discuss how to send messages between the PA and the consuming application.

Our application will be a ‘search’ application that has two different search engines (Engine One and Engine Two).  The PA will present the search forms and the search results.   The search strings will be sent to the consuming application to run the searches.  After the search is performed the results will be sent back to the PA to be displayed.

Requirements

The MVCContrib library which can be downloaded from MVCContrib download at CodePlex.  You will also need MVC 2 installed to be able to run the sample application.  I have built the example application using Visual Studio 2010.  I am planning on creating VS 2008 versions as well.

Lets Get Started!

The first thing we need to do is create the two projects, an MVC2 project for the consuming application, I named mine ConsumingApp,  The second project is a class library project for the PA, which I called ViewsPA.  Below are the required references:

  1. ConsumingApp: 
    • MVCContrib.dll
    • And a reference to ViewsPA project
  2. ViewsPA:
    • MVCContrib.dll
    • System.ComponentModel.DataAnnotations
    • System.Web
    • System.Web.Mvc
    • System.Web.Routing

ViewsPA

Since we talked about the layout of the code for the PAs in Part 1 - The Basics I won’t go into that here.  I will talk about the parts of the project that pertain to messaging.

The communication between the PA and consuming application is done via a synchronous message bus provided by the MVCContrib library.  Messages that are put on the bus by the PA must implement the MvcContrib.PortableAreas.ICommandMessage<T> interface where T is implements the ICommandResult interface.  The ICommandResult class is used by the consuming app to return the results to the PA.  Enough of this…here is the PA’s side of the messaging in C#.

SearchResult SearchMessage

In the SearchResult class the Success property is from the ICommandResult interface.  The remaining properties are there to illustrate the fact that you can have any number of properties and types of properties in the ICommandResult classes. 

The SearchMessage class is what is sent to the consuming application.  It implements the ICommandMessage<T> interface where the SearchResult class takes the place of T.  When you implement the interface the Result property must be the same type as T.  The Input property is a Query class which is a POCO and sends the search string to the consuming application.

The last bit of code I want to show is the controller’s action method.  Since both SearchOne and SearchTwo are doing the same thing but just setting which ‘search engine’ to use I have created a base controller class to make life easier.  The base class is here to process the user’s form submission and passes the query string to the consuming application.    SearchControllerBaseClass

 

The first line is a normal POST handling method.  However once the model has been validated the controller starts the messaging process.

The first step is to create and load  a  SearchMessage object that will be sent consuming application.

Next the object is put on the bus and sent to the consuming application.

When the message is returned from the consuming application the method checks for success or failure of the processing.  If it fails do something to inform the user otherwise display the results of the ‘search’. 

That is all we need to do on the PA side.  We added a few classes and lines of code to enable our PA to communicate with the consuming application.

Consuming App

In our consuming application we need to create a class to handle the incoming messages from the PA and wire up global.asax to register our message handler with the messaging bus.

First we’ll take a look at what code we need to add to the global.asax file.  We need to add one line to the Application_Start method to receive the message being sent from the PA.  We added a line that calls the Bus.AddMessageHandler method to notify the bus that we have a message handler of type SearchHandler.  That class will handle all of our SearchMessage based messages from the PA. 

The SearchHandler class inherits from the MessageHandler<T> class where T is the message that this handler will ‘handle’. Our class will override the Handle method from MessageHandler.  This method is where we will do what we need to fulfill the PAs message.  Hopefully looking at the code will make it a little more understandable.

The Handle method has a single parameter of type T. In our make believe search engine case our method checks to see what engine the PA requested.  Instead of doing an actual search I am putting a canned message in the result object’s Message property that indicates which engine handled the request.  The Message and Results properties are used in the PA’s results view.  After this method finishes the PA’s controller method will pick up the results and call the appropriate view.

part2-global-asax part2-messagehandler

That is all there is to setting up messaging between the PA and the consuming app.

Lets Try It!

The home page is just about the same as it was in part 1 except that there are two tabs from the PA, Search One and Search Two.

part2-tabs

 

 

 

 

 

 

 

 

Clicking on the Search One tab will take us to our new search form.  We have a second field here to distinguish between ‘search engines’.  When I submit my search string the PA sends the request to the consuming application which does the search and returns the results to the PA.  The results will display the name of the engine used and the results also indicate which engine returned the results.

part2-search-form part2-results

Summary

Adding messaging to our search application only requires slight modification to our consuming application.  First we created a MessageHandler<T> based class that will respond to the PA’s message.  Next we added a line to the global.asax’s Application_Start method to register you handler class with the message bus. 

There was a little more work required on the PA side.  We had to alter the action method to send the message to the consuming application.  Once the consuming app is done the PA checks the results sent back the remaining portion of the action method is normal controller actions.

Why Would You Do This?!

Some of you may be wondering why you would do something like this with just the views on the PA.  Where I work we may be using this approach to create an application framework with pluggable modules for different sites.  The middle and data layers will be the same across all sites but certain locations will only use a few of the views.  This approach will help us create multiple sites without having to create a complete web site for each location.

What’s Next…

Part 3 of the series will either be on adding MEF to the picture or how to access a web.config file in the PA project. 

Downloads

Monday, June 14, 2010

Back from Tech-ED and I have OData Fever!

The title sums it up.  I am in the middle of an OData fit.  In my free time I am working on compiling baseball statistics from the Baseball Databank and Retrosheet sites to create one stats database that is available using OData.  I’m not sure how long it will take but I will have it up some time in the future.

What is OData?!

“The Open Data Protocol (OData) is a Web protocol for querying and updating data that provides a way to unlock your data and free it from silos that exist in applications today.” – taken from OData.org 

Serving data up this way frees us developers from some of the headache of cross platform data access (well at least those of us who primarily write for the windows platforms).  There are already quite a few client libraries out there to consume OData (PHP, Java, etc..).

I may have a few blog entries about OData and how to set it up on the server and client sides.  I still haven’t really thought it through all the way quite yet.

Why should I care about your fever?

If you are a baseball fan you will have access to historical data free of charge ready to use for whatever you can dream up.  In addition to the feed I plan on having a small app or two to demonstrate how to use the data and/or to query the data.

If you aren’t a baseball fan but are curious about OData then you may want to check back periodically to check my status.  I’m sure as I run into issues and/or figure things out I’ll blog about them.

Now if I could only find a few more hours to put into my day I could get this all done quickly.

Friday, June 11, 2010

MVCContrib – Portable Areas – Part 1

Update: After seeing a post on StackOverflow.com I have updated my sample code to work with the latest MvcContrib available through NuGet that supports MVC 2.

This is the first of a series of posts on how to use the MVCContib project’s portable areas functionality. Throughout this series we will be building out a ‘search’ application that utilizes portable areas (PAs) to provide the search functionality.  The consuming application is a relatively ‘dumb’ application that is used as a framework to serve up our PAs. 

In this entry I will discuss what libraries are necessary to use portable areas, how to configure your solution and projects and we will end the post with a basic web application runs a search using Bing.com.   The source code for this post can be found at MVCContrib Portable Areas - Example App at bitbucket.org

Requirements

The MVCContrib library which can be downloaded from MVCContrib download at CodePlex.  You will also need MVC 2 installed to be able to run the sample application.  I have built the example application using Visual Studio 2010 – Ultimate as my IDE but I will also include a vs2008 Professional version of the project.

Lets Get Started!

Start up Visual Studio and create a new ASP.NET MVC 2  Web Application to be the consuming application project, I named mine PortableAreas – Consuming App.  Next we need to create a Windows Library project which will be our portable area library, I named mine SearchPA project.   After creating the projects add the following references:

  1. PortableAreas – Consuming App: 
    • MVCContrib.dll
    • And a reference to SearchPA project
  2. SearchPA:
    • MVCContrib.dll
    • System.ComponentModel.DataAnnotations
    • System.Web
    • System.Web.Mvc
    • System.Web.Routing

The SearchPA Project

imageThe layout of this project will be similar to a normal MVC project with a few changes.  The first change is the Bing folder.  Since we are starting off with Bing search all Bing related code will be under this folder.  The Controllers, Models, and Views folders are exactly the same as a normal MVC project.  The Messages folder will contain classes that are used to communicate with the consuming application.  We will talk more about Messages in the next post.  The other difference is the BingRegistration.cs file.

The BingRegistration class is used to register our PA with the consuming application and to inform the view engine about the presence of our routes and views.  It inherits from the class MvcContrib.PortableAreas.PortableAreasRegistration. From this class we override the RegisterArea method which has two parameters: AreaRegistrationContext and an IApplicationBus object.  The AreaRegistrationContext is used to map the Bing related routes.  The IApplicationBus is used for messaging between the PA and consuming app.  For now we are going to ignore the IApplicationBus but we will be used in the next post of the series.  After the routes are added we call a method to register the views with the view engine as you can see below.  The last task we need to do is override the AreaName property to set it to Bing.

There is one thing to keep in mind when you create your registration class, it must be at the base namespace of the controllers.  If the class in not in this namespace the portable area will not work.   

After the registration class has been completed the coding of the controllers and the models are the same.  In our case we will have an HTTP GET and HTTP POST version of an index method in the BingController class.  The contents of these methods are exactly the same as they would be for a ‘normal’ MVC app so I will let you read the code when you download the sample app.

The views in portable area are programmed in the same manner as normal views.  The only difference between the ‘normal’ MVC app’s views and the views in this project are that you must set them up as an embedded resource. Setting up a PA's View as an Embedded Resource  This allows the views to be packaged into the dll and the only thing the consuming application needs to do is add a reference to the SearchPA.dll.  In order to set up the view right-click on the view in the Solution Explorer and select Properties from the menu.  Select the Embedded Resource from the Build Action drop down.  Once that is done your view is ready. And with that we are done with the SearchPA project.

 

The Consuming MVC App

There are only a couple of additions needed to the MVC application in order to use our SearchPA portable area.  The first is configure the Global.asax file.

The code snippet above is from the global.asax file.  The only addition to this file for Part 1 of this series is the InputBuilder.BootStrap() line.  This line is necessary to initialize the embedded view engine used by the PAs.  In Part 2 we will add code to this method to allow communication bet the PA and consuming application.

The second modification is in the web.config file under the Area’s folder. The Areas/Web.Config file is needed to allow us to display the views that are part of the SearchPA project.  If you do not have this web.config file with the settings displayed below you will receive the error message below. 

Parser Error - Google Chrome

The Areas/Web.config file is used to set the pages attribute validationRequest=”false”.  This allows the the embedded views to be served by the consuming application.

Let’s Try It!

Now that we have everything set up hit F5 and lets run the application. On the home page the Bing Search tab is from the SearchPA project.  Clicking on the ‘Bing Search’ tab is when the code that is part of the PA kicks in.

Home Page - Google Chrome

Here’s the search form.  This form is embedded into the SearchPA.dll.  When I do a search for ‘MVCContrib’ the results will be displayed by the results view in the SearchPA.  The consuming application does nothing but handle the routing.

Home Page - Google Chrome (2)

And here is the results view…

Search Results Page - Google Chrome

Summary

Now we have a functional Bing search application using the MVCContrib Portable Area functionality.  We went over what you’ll need (MVCContrib download at CodePlex and ASP.NET MVC 2) and how to setup both projects for a self-contained portable area project.

What’s Next…

In the next article we will go over how PAs can communicate with the consuming application.

Downloads