6

I'm using 51 degrees on my MVC site as an adaptive approach to serving my pages. All is working well.

I have recently added output caching and I use the VaryByCustom to check whether it is mobile or desktop:

    public override string GetVaryByCustomString(HttpContext context, string custom)
    {
        // this is for the output cache
        if (context != null)
        {
            switch (custom)
            {
                case "Mobile":
                    return GetMobileCustomString(context);
            }
        }

        return base.GetVaryByCustomString(context, custom);
    }

    private static string GetMobileCustomString(HttpContext context)
    {
        if (context.Request.Browser.IsMobileDevice)
        {
            return "IsMobile";
        }
        else
        {
            return "IsDesktop";
        }
    }

However I have run into a problem that if the first mobile user to browse the site has requested the desktop version, this will be cached for all mobile users.

I need to change the GetMobileCustomString to include a check for if it is a mobile requesting a desktop site. Is there any way to do this?

Update

As a bounty has been opened on this, I thought I would offer an update:

Firstly, it was not the first load causing the desktop page to be cached as I had initially thought, so having done a lot of searching, research and testing on this, I feel the desktop page should never be cached for the mobile version (if you are on MVC 5). I have stepped through the code when doing a mobile request and when it gets to the vary by custom, it shows context.Request.Browser.IsMobileDevice as false.

Not sure what is causing the desktop site to be cached for the mobile site - perhaps it is a hangover from the bug in MVC 4. It just seems to be random (ie, one day it will be fine and then another day it will be serving the desktop site for some reason) and recycling the app pool will always fix it.

I also found that I could get the overriden browser by using:

using System.Web.Wepages;

context.Request.RequestContext.HttpContext.GetOverriddenBrowser();

But it didn't seem to be much use

Community
  • 1
  • 1
  • Do you have permissions to change desktop/mobile apps and the request? Maybe you could set an user-agent of the http request and read from it. – Felipe Oriani Oct 07 '16 at 11:39
  • 1
    Is there no built in way, when I was searching, I came across this where you can explicitly set the override browser: http://stackoverflow.com/questions/16080593/mvc4-force-mobile-site-for-all-requests-including-desktop. If you can set it, is there no way to get it? – Pete Oct 07 '16 at 11:47
  • hmmm, having looked more into that browser override, it would seem that the override is just set by a const string: https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.WebPages/BrowserHelpers.cs – Pete Oct 07 '16 at 14:40
  • 1
    Why not something with setting a cookie when the user requests the Desktop site? Then read the cookie, and alter accordingly. – krillgar Oct 07 '16 at 14:44
  • @krillgar having done a bit more testing after seeing amateur's update my problem would be that if a user comes straight in on a mobile requesting a desktop site, the device is classed as a desktop so that would bring me back to the original question - how do you tell if it is a mobile requesting a desktop site? - Ps it's not a button on the site that requests the desktop version, it's a setting on the phone – Pete Oct 10 '16 at 12:44
  • Just an update. I sent an email to 51 degrees support and basically they have told me that I would need to check the user agent for this. Although I would need to check it against one already stored to see if it changed so basically, there isn't a way to see if a mobile user requesting the desktop site has come straight into the site (requesting desktop) – Pete Oct 14 '16 at 11:56

2 Answers2

0

It seems to me like what you are doing should work, provided you are storing the cache at the client side.

You should be using the OutputCache attribute on your controller actions in the following manner:

[OutputCache(Duration = 5, VaryByCustom = "Mobile", Location = OutputCacheLocation.Client)]

(The duration is up to you)

That being said, browser detection is based on HTTP headers so nothing is going to help you if the requesting browser is sending headers for a different agent.

The other option is to use feature detection instead.

I hope that helps.

JuanR
  • 7,405
  • 1
  • 19
  • 30
0

Within the 51degrees.config there is a setting

 <redirect devicesFile="" timeout="20" firstRequestOnly="true"

This firstrequestonly may be confusing your caching system so treating the first mobile device as the first request, and all other mobiles as the same session of the original mobile device. Try setting this to false and see if that helps solve your issue.

Zarwalski
  • 69
  • 1
  • 9