Setup MVC 3 with Dependency Injection and Mobile support (IPhone, IPad, Windows Phone) in a few minutes!

by 27. March 2011 12:05

Not that it took me only five minutes....   I was able to gleen bits and pieces from different sites, however most of the information available (as of this date) applies to beta code that doesn't work with the latest MVC 3 release.  As a result this task started yesterday (Saturday) at approximatey noon and I am just now wrapping it up (Sunday evening 9:00pm)....   Lots of dead-ends and misinformation.... Fortunately I ran into Brad Wilson's site which started to streamline the process by filling in the blanks.

Why did I have to bleed?   I am writing my wife a new website for her business that will automate all of her mundane tasks.   This week she is at home (Amarillo, TX) taking care of her business while I am on location for an out-of-state contract; I proudly tell her "check out the site!".  She calls me back and my pride quickly turned to an unexpected jaw drop - she said "I just accessed the site with my sister's IPad and I can't see the movies - I get a Silverlight button that won't install - it isn't supported".  Naturally she turned to her IPhone next with similiar results - except the screen was real tiny.   

We don't want to limit her client base to desktops (particularly in this day and age of IPhone/IPad) so I am starting to see an early return on investment for my new Mac Pro plus (I'll also be writing her IPad/IPhone apps).  Sure enough, when I accessed the site with both the IPhone and IPad emulators I quickly saw that the site was not where it needed to be.  Early in the research process I learned I can use MP4's for both of these devices so the top priority was providing mobile support for her MVC 3 site.  As of this writing only the IPhone/Windows Phone pages have an MP4 sample - IPad is a work in progress).

Cool Hopefully this will save you some time

Source code: Gwn.Library.TestHarness.zip (4.04 mb)

Setting up a brand new MVC 3 project with Unity (DI) and Mobile support

  1. Create the new MVC 3 project and add a reference to the Gwn.Library.Desktop project
  2. Copy the Mobile folder to the "Views/Home" folder
  3. Copy the _LayoutMobile.cshtml file to the "Shared" folder 
  4. Update the _ViewStart.cshtml as shown in the top right pane (image below)
  5. Update the Global.asax.cs file with lines 43-54 below

Your done!

You'll want to use the IE 9 developer tools to easily switch "user agents" between IPhone, IPad, Windows Phone, and Desktop modes.   Once I launch the application in debug mode I simply hit F12 to open the developer tool view, select Tools, Change User Agent string, and select the platform I am developing/testing for.   Note that the non-desktop devices do not have tabs - this is configurable from the applicable extension.

Below are the custom settings I used for the three platforms - I prefix with a forward slash because the code will do a IndexOf > 0 so I need to ensure my mock agent string does not start at zero.   The current settings used for development worked for the IPhone, IPad and Windows Phone hardware devices.

Once you select a new user agent you simply have to go back to the browser and hit refresh - it will use the specified user agent!

Deploying ASP.NET MVC 3 with Razor to a Windows Server without MVC installed on host

by 19. March 2011 10:29

The fun on this issue started when I tried to deploy a basic MVC 3 framework (stock-out-of-the-box) to my ISP server and received the following error:

"Could not load file or assembly 'System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified."

My assumption was that this namespace resided under System.Web.WebPages namespace since my project had no reference to a System.Web.WebPages.Razor assembly.   In this experience I learned that it is best to start debugging issues at  Scott Hanselmins blog; this is the second time in a week that he has helped me through a "bleeding edge" issue that was causing me to hemorrage....

I appreciated that he started this blog with the following quote - it clarified the meaning of "Bin Deploy"

If someone says "just bin Deploy it" they mean "deploy the application with the dependencies copied into the application's /bin folder, rather than running an MSI that installs the dependencies into the Global Assembly Cache (GAC)."

Even though this blog BIN Deploying ASP.NET MVC 3 with Razor to a Windows Server without MVC installed didn't resolve my issue completely (I ran into more issues) the comments within his blog helped fill in the blanks.  

In summary - follow his instructions for "The Manual Way to BIN Deploy ASP.NET MVC 3 with Razor" which will have you manually copy the following five files to the bin folder (I manually FTP them to the server's bin since I was debugging/troubleshooting):

  1. System.Web.Mvc  (I selected this dll from the references list and changed its "Copy local" property setting to True to resolve this requirement
  2. System.Web.Infrastructure.dll
  3. System.Web.Helpers.dll
  4. System.Web.Razor.dll
  5. System.Web.WebPages.dll
  6. System.WebPages.Razor.dll

From the Program Files(x86)/Microsoft ASP.NET/ASP.NET Web Pages/v1.0/Assemblies folder, which quickly dispelled my belief that the razor namespace was in System.Web.WebPages; I see now that the dependencies were solved externally.

You'll quickly find that you will require a 7th file

     7.  System.Web.WebPages.Deployment.dll (from the same folder as the above)

2011.03.27 UPDATE

 It is actually easier than noted above!!!

I understand this came with VS 2010 SP1

Right click on your MVC 3 web applicaiton and select "Add Deployable Dependencies" 

Select ASP.NET MVC (it will provide everything you need for the RazorViewEngine)

When done you will have the required assemblies in a _bin_deployableAssemblies folder! 

ASP.NET MVC - MapRoutes for data driven views

by 25. September 2010 23:38

The Community Starter Kit (CSK) is a data driven application; there are no actual web pages.   When I upgraded the CSK to support ASP.NET Beta 2 (Microsoft abandoned support of the CSK) I renamed it the Community Advanced Starter Kit (CASK) because it was off the beaten path and required advanced skills to understand (learning curve was steep).

CASK seems to have a following and is a perfect tool to help me learn/master the ASP.NET MVC environment; so I'll use this opportunity to upgrade CASK to version 3.0.  I am finding that ASP.NET MVC is lending itself to the "data driven" environment that CASK thrives in.  

The first thing I have to do is configure the routes so that ASP.NET MVC does not complain if the requested view does not exist.  The following are the behaviors I was looking for:

  1. It had to support default behavior.   I don't want CASK V3 to be far off the beaten path (like CSK was to ASP.NET developers); I'd like people learning (or knowledgable) of ASP.NET MVC to be able to quickly ramp up.   It also will have great value for the functionality that will have actual pages such as the admin section.
  2. I needed it to support simple addresses, e.g., http://mydomain/1?hello=world
  3. I needed it to support the dynamic address generated by CASK, e.g., http://mydomain/Main/Section/Detail

The following meets these requirements (documented in detail after the image):

Getting my mind around MapRoute was tricky because there wasn't a lot of documentation on the subject.  Fortunately Scott Hanselman has great webcast on the subject and with his Nerd Dinner demo I was able to figure out how to configure my routes.  I used Phil Haacks route debugger to work out the details as it is not straight forward as one would think; at least not with available documentation.

To keep the default behavior, and get the other behaviors I required, I first had to remove the "id" from the default MapRoute (line 35 above).   With that change the default pages, to include login, continued to work while opening up three segments to CASK, e.g., http:mydomain.com/1/2/3.   This took care of my first requirement, now the HomeController will intercept any addresses that have two segments, e.g. mydomain/Home/Main which is acceptable for the purposes of CASK (it's addresses will have more segments OR contain a single segment).

Next I needed all other segments counts to be handled by the CaskController so that it can dynamically load the applicable content from the database.  I found I was able to successfully achive this for any segment count > 2 using the CaskAll MapRoute on line 40.   Note the "*caskAll" has an asterisk, I got this from Scott's Nerd Dinner sample and found that without this wildcard, the behavior I was seeking was not there (couldn't find documentation on the asterisk but it worked!).

With the noted addition I was surprised that it didn't pick up the single segment, e.g, mydomain/1?hello=world.   I couldn't move CaskAll before the default MapRoute or I would lose the default behavior so I added the CaskId MapRoute on line 27 and all worked as required.

The following is the controller code and debug information when this address
http://localhost:16311/1?Hello=World  is typed in:

Notice

Blog videos and references to CodePlex projects are no longer valid