MobileViewEngines / Helpers / MobileCapableWebFormViewEngine.cs

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Mvc;

namespace Microsoft.Web.Mvc
{
    public class MobileCapableWebFormViewEngine : WebFormViewEngine
    {
        public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName,
                                                  string masterName, bool useCache)
        {
            string overrideViewName = controllerContext.HttpContext.Request.Browser.IsMobileDevice
                                          ? viewName + ".Mobile"
                                          : viewName;
            ViewEngineResult result = NewFindView(controllerContext, overrideViewName, masterName, useCache);

            // If we're looking for a Mobile view and couldn't find it try again without modifying the viewname
            if (overrideViewName.Contains(".Mobile") && (result == null || result.View == null))
            {
                result = NewFindView(controllerContext, viewName, masterName, useCache);
            }
            return result;
        }

        private ViewEngineResult NewFindView(ControllerContext controllerContext, string viewName, string masterName,
                                             bool useCache)
        {
            // Get the name of the controller from the path
            string controller = controllerContext.RouteData.Values["controller"].ToString();
            string area = "";
            try
            {
                area = controllerContext.RouteData.DataTokens["area"].ToString();
            }
            catch
            {
            }

            // Create the key for caching purposes           
            string keyPath = Path.Combine(area, controller, viewName);

            // Try the cache           
            if (useCache)
            {
                //If using the cache, check to see if the location is cached.               
                string cacheLocation = ViewLocationCache.GetViewLocation(controllerContext.HttpContext, keyPath);
                if (!string.IsNullOrWhiteSpace(cacheLocation))
                {
                    return new ViewEngineResult(CreateView(controllerContext, cacheLocation, masterName), this);
                }
            }

            // Remember the attempted paths, if not found display the attempted paths in the error message.           
            var attempts = new List<string>();

            string[] locationFormats = string.IsNullOrEmpty(area) ? ViewLocationFormats : AreaViewLocationFormats;

            // for each of the paths defined, format the string and see if that path exists. When found, cache it.           
            foreach (string rootPath in locationFormats)
            {
                string currentPath = string.IsNullOrEmpty(area)
                                         ? string.Format(rootPath, viewName, controller)
                                         : string.Format(rootPath, viewName, controller, area);

                if (FileExists(controllerContext, currentPath))
                {
                    ViewLocationCache.InsertViewLocation(controllerContext.HttpContext, keyPath, currentPath);

                    return new ViewEngineResult(CreateView(controllerContext, currentPath, masterName), this);
                }

                // If not found, add to the list of attempts.               
                attempts.Add(currentPath);
            }

            // if not found by now, simply return the attempted paths.           
            return new ViewEngineResult(attempts.Distinct().ToList());
        }
    }
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.