Search code examples
c#asp.net-mvcbrowser-cacheurlhelper

How to inject descendant UrlHelper class into WebViewPage to enable cache busting?


I've overridden UrlHelper.Content() method. Now I want my implementation to be used instead of default UrlHelper class.

How can I configure MVC to tell it which class to inject into WebViewPage.Url property?

Update 1:
The idea is simple. Bundles support cache busting by adding timestamp query parameter to the url.
I want the same functionality for single resource.
UrlHelper class allows to override its Content(string) method. Consequently it is possible to take resource's timestamp into account when generating final string.

Update 2:
It seems like my premise was wrang. I thout that src="~..." is equivalent to src="@Url.Content("~...")". That is not the case.


Solution

  • You're gonna need to introduce your own WebViewPage that is providing its own implementation of UrlHelper which will override the Content() method.

    First, create the types:

    public class MyUrlHelper : UrlHelper
    {
        public MyUrlHelper() {}
        public MyUrlHelper(RequestContext requestContext) : base(requestContext) {}
        public MyUrlHelper(RequestContext requestContext, RouteCollection routeCollection) : base(requestContext, routeCollection) { }
    
        public override string Content(string contentPath)
        {
            // do your own custom implemetation here,
            // you access original Content() method using base.Content()
        }
    }
    
    public abstract class MyWebPage : WebViewPage
    {
        protected override void InitializePage()
        {
            this._urlHelper = new MyUrlHelper(this.Request.RequestContext, RouteTable.Routes);
        }
    
        private MyUrlHelper _urlHelper;
        public new MyUrlHelper Url { get { return _urlHelper; } }
    }
    
    // provide generic version for strongly typed views
    public abstract class MyWebPage<T> : WebViewPage<T>
    {
        protected override void InitializePage()
        {
            this._urlHelper = new MyUrlHelper(this.Request.RequestContext, RouteTable.Routes);
        }
    
        private MyUrlHelper _urlHelper;
        public new MyUrlHelper Url { get { return _urlHelper; } }
    }
    

    Then register your custom MyWebPage in ~/Views/Web.Config:

      <system.web.webPages.razor>
        ....
        <pages pageBaseType="Your.NameSpace.MyWebPage">
             ....
        </pages>
      </system.web.webPages.razor>