views:

53

answers:

3

We are building a closed system using ASP.NET MVC. There are multiple touchpoints in this demo system, but all will be running browsers. All will be showing basically the same data, but the targets differ in several ways:

  1. Screen size and orientation. We have some at full HD, and others at 800x480. Some are portrait and some are landscape, but all are known and will not change.
  2. Because of this, the views will be fundamentally different, and will be designed that way.

My question is this: should I create a separate controller for each target type and page, or should the controller somehow interpret which target type and deliver the appropriate view? For example, should I do this:

TargetType1AccountController
TargetType1HomeController
TargetType2AccountController
TargetType2HomeController

or this:

AccountController/TargetType1View
AccountController/TargetType2View
HomeController/TargetType1View
HomeController/TargetType2View

+2  A: 

I would go with your second approach and:

  • try do do as much with CSS as you can before resorting to alternate views
  • if alternate views are needed, they should share the same controller, since most of the logic should be identical or very similar
  • make use of partials to share snippets of HTML that are common between views
RedFilter
+4  A: 

I would recommend you writing a custom view engine. This way your structure might look like this:

  • Views
    • Home
      • Index.aspx // default version
      • UA1
        • Index.aspx // version for user agent 1
      • UA2
        • Index.aspx // version for user agent 2
    • Shared

And then have a custom view engine:

public class CustomViewEngine : WebFormViewEngine
{
    public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
    {
        string ua = controllerContext.HttpContext.Request.UserAgent;
        if (ua == "UA String 1")
        {
            return base.FindView(controllerContext, "UA1/" + viewName, masterName, useCache);
        }
        if (ua == "UA String 2")
        {
            return base.FindView(controllerContext, "UA2/" + viewName, masterName, useCache);
        }

        return base.FindView(controllerContext, viewName, masterName, useCache);
    }
}

And finally register the view engine in Application_Start:

ViewEngines.Engines.Clear();  
ViewEngines.Engines.Add(new CustomViewEngine());

This way your controller and actions are strictly the same and based on the User-Agent HTTP header the proper view will be used. All you need to do when you have to handle UA3 is to add the corresponding view in a UA3 folder. No need to touch the controllers and models.

Darin Dimitrov
+1  A: 

All will be showing basically the same data, but the targets differ in several ways:

  1. Screen size and orientation. We have some at full HD, and others at 800x480. Some are portrait and some are landscape, but all are known and will not change.
  2. Because of this, the views will be fundamentally different, and will be designed that way.

Use the same controller, since the data is the same. I'd only introduce a different controller if the operations were differently / or needed to retrieve the data in a very different way. Even with variations of the data, it might still be a case to use the same controller.

If its only visual aspects you should be able to do it with css. Check all the alternative designs in the css Zen Garden, all share the same html.

If you do need different views, then make sure those are specially simple. Move as much you can to the controller / view models.

There is more than 1 way to apply the different views with the same controller:

  • Custom Engine like @Darin mentioned. Make sure it falls backs to use the default view if the specific one isn't defined, that way you can define the specific views only when you really need it.
  • An Action Filter that switches the view to be used
  • A custom View Result, that instantiates a new view result pointing to the appropriate view. Similar to this asp-net-mvc-hybridviewresult-viewresult-partialviewresult (that one is for partialresult vs. viewresult, but the concept is the same).
eglasius