简体   繁体   中英

ASP.NET MVC5 - append querystring to all URLs

My team is building a simple MVC site for very low end "feature" phones. One problem we have is that certain phone aggressively cache HTML, so what the user actually gets to see is not what we intend. An extreme example is, a user registers and gets a "thank you page". Another user on the same device then tries to register. The phone simply serves the cached page without creating a new account.

In the past I've dealt with this by adding a "cache buster" querystring to things I don't want cached, eg all pages will be served in the format

http://domain.com/controller/route?cb=somerandomstringofnumbers

In this case we'd need to do this for all URLs in the site - this includes the URLs auto-generated by Controller actions such as RedirectToAction or Redirect and also the Razor Url.Action , Html.BeginForm , Html.ActionLink etc.

Now obviously I could decorate the Razor HTML helpers (or extend them) and add the argument to an controller action, but it seems to me that because the actual URLs generated by these built in methods are auto-generated from the Controller/Action params passed in, there should be a way to hijack that process.

Unfortunately the MS classes are protected - I'm mostly looking in System.Web.Routing.Routes.

I've tried a few things I've found online but they are not MVC5 (dating back to 2008) and it seems the framework has changed significantly.

eg, from http://forums.asp.net/t/1216840.aspx?Append+value+to+all+urls+built+by+RouteCollection+GetUrl

public class SessionAppendingRouteHandler : IRouteHandler
{
   public IHttpHandler GetHandler(RequestContext context)
   {
       SessionAppendingHttpHandler handler = new SessionAppendingHttpHandler();
       handler.RequestContext = context;
       return handler;
   }
}




public class SessionAppendingHttpHandler : MvcHandler
{
    public override ProcessRequest(RequestContext context)
    {
          //append your sid here
    }
}


// and in the route setup

RouteTable.Routes.Add( new Route
{
   Url = "/[controller].mvc/[action]/",
   Defaults = new { action = "index" },
   RouteHandler = typeof(SessionAppendingRouteHandler)
});

This I cant get to work as the framework has changed too much, but it looks very close to what I would like to achieve.

I feel like I'm in the right area, but I've hit a brick wall.

Any suggestions?

This is quite old, but let me answer based on how I solved a similar problem:

Instead of having it as query string, have the cb as a route value just as action and controller are route values. You can do this by registering a route; for instance:

 routes.MapRoute(
     name: "CB",
     url: "{cb}/{controller}/{action}/{id}",
     defaults: new { cb = "3600", area = "", id = UrlParameter.Optional }
 );

If the value for cb is not a constant, then you can find a convenient point to set the cb for each user session. A good place will be after a successful login. With this, you'll now need to provide just two custom methods for RedirectToAction and ActionLink . Your implementation will simply package a RouteValueDictionary and then pass it in to MVC's own implementation using the appropriate overloads.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM