1

I ask because I'm noticing on my site, if I hit it with an iPhone, sometimes it shows the mobile views, sometimes it shows regular views.

I've also read that MVC 4's not particularly effective at determining if the browser is from a mobile device or not, is that true? If so, anything we can do about it?

Chaddeus
  • 13,134
  • 29
  • 104
  • 162
  • Are you always hitting your site from the same iPhone? Same page? – Darin Dimitrov Jul 16 '12 at 05:54
  • @Darin, Yes... same iPhone, same page. Even had the problem persist over a few refreshes, then "found" the mobile views. – Chaddeus Jul 16 '12 at 06:25
  • See if this helps.It talks about the problem you are facing and It uses custom View Engine to render view according to the request http://stackoverflow.com/questions/1387354/how-would-i-change-asp-net-mvc-views-based-on-device-type – Anand Jul 16 '12 at 10:55
  • See http://forums.asp.net/t/1824033.aspx – RickAndMSFT Jul 16 '12 at 18:53
  • 2
    We have confirmed this is a bug. The bug will be fixed out of bound after MVC 4 RTM ships. – RickAndMSFT Jul 16 '12 at 19:18
  • Thank you Rick! Is there a workaround until the bug gets resolved? – Chaddeus Jul 17 '12 at 00:04
  • Not yet. Monitor http://aspnetwebstack.codeplex.com/workitem/280 – RickAndMSFT Jul 19 '12 at 01:39
  • I added `ViewEngines.Engines.OfType().First().ViewLocationCache = DefaultViewLocationCache.Null;` to App Start in Global.asax, that doesn't seem to have worked around the bug. Still get page load errors on mobile. – Chaddeus Jul 22 '12 at 08:29

1 Answers1

0

Update: Microsoft have published a workaround package for this bug.

I have added this workaround at here,

public class MyDefaultViewLocationCache : DefaultViewLocationCache, IViewLocationCache
{
    public MyDefaultViewLocationCache(TimeSpan timeSpan): base(timeSpan)
    {
    }
    public MyDefaultViewLocationCache()
        : base()
    {
    }

    public new string GetViewLocation(HttpContextBase httpContext, string key)
    {
        var location = base.GetViewLocation(httpContext, key);
        if (location == null)
        {
            var cache = httpContext.Cache;
            RemoveAllCacheStartWith(key, cache);
        }
        return location;
    }

    private static void RemoveAllCacheStartWith(string key, System.Web.Caching.Cache cache)
    {
        var keyWithoutDisplayMode = key.Substring(0, key.Substring(0, key.Length - 1).LastIndexOf(':') + 1);
        var items = new List<string>();
        var enumerator = cache.GetEnumerator();
        while (enumerator.MoveNext())
        {
            var _key = enumerator.Key.ToString();
            if (_key.StartsWith(keyWithoutDisplayMode))
            {
                items.Add(_key);
            }
        }
        foreach (string item in items)
        {
            cache.Remove(item);
        }
    }

    public new void InsertViewLocation(HttpContextBase httpContext, string key, string virtualPath)
    {
        base.InsertViewLocation(httpContext, key, virtualPath);
    }
}

// In App Start
ViewEngines.Engines.OfType<RazorViewEngine>().First().ViewLocationCache =
new MyDefaultViewLocationCache();

For detail see this.

imran_ku07
  • 1,404
  • 12
  • 13