【问题标题】:How to inject descendant UrlHelper class into WebViewPage to enable cache busting?如何将后代 UrlHelper 类注入 WebViewPage 以启用缓存破坏?
【发布时间】:2014-10-29 09:34:41
【问题描述】:

我已经覆盖了UrlHelper.Content() 方法。现在我希望使用我的实现而不是默认的 UrlHelper 类。

我如何配置 MVC 来告诉它哪个类注入WebViewPage.Url 属性?

更新 1:
这个想法很简单。捆绑包通过向 url 添加时间戳查询参数来支持缓存破坏。
我希望单个资源具有相同的功能。
UrlHelper 类允许覆盖其 Content(string) 方法。 因此,在生成最终字符串时可以考虑资源的时间戳。

更新 2:
看来我的前提是错误的。我认为 src="~..." 等同于 src="@Url.Content("~...")"。事实并非如此。

【问题讨论】:

    标签: c# asp.net-mvc browser-cache urlhelper


    【解决方案1】:

    您需要引入自己的WebViewPage,它提供了自己的UrlHelper 实现,它将覆盖Content() 方法。

    首先,创建类型:

    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; } }
    }
    

    然后在~/Views/Web.Config中注册您的自定义MyWebPage

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

    【讨论】:

    • 谢谢,我现在试试。
    • 是否需要引入新的Url属性?我认为设置基本 WebViewPage 的 Url 属性值就足够了。
    • 由于WebViewPage.Url是一个非虚拟属性,你需要使用new关键字来隐藏它。
    • 您需要Url 属性指向您的自定义MyUrlHelper
    • 我只需要多态行为,MyUrlHelper 类不包含其他属性。所以 Url 属性在这里就足够了,至少我希望如此。
    【解决方案2】:

    我没有直接回答您的问题,但您可以像这样创建 URLHelper 类的扩展:

    public static class CustomUrlHelper
    {
        public static string CustomContent(this UrlHelper helper, string contentPath)
        {
            // your Content method 
        }
    }
    

    然后像这样在Url 对象上调用这个方法:

    @Url.CustomContent("~/Content/Site.css")
    

    【讨论】:

    • 这在我们的例子中是行不通的。坦率地说,我不确定“覆盖”是否也会有所帮助。我们在 url 中使用波浪号:'src="~...."' MVC4 将这些 url 转换为正常的。我希望它能调用 Url.Content。
    • @voroninp 很遗憾听到这个消息。当您说“MVC4 将这些 url 转换为普通 URL”时,您的意思是它将“~/Content/Site.css”转换为“/Content/Site.css”,并且您需要将其转换为“~/Content/Site.css”。 css”?
    • 不完全是。我只想转换考虑文件时间戳。用于缓存破坏。所以,当我写 src="~Scripts/my.js" 时,我希望最终结果是 src="VirtualDirPath/Scripts/my.js?
    • @voroninp,你最好使用捆绑包。
    • @voroninp 好吧,我刚刚尝试过,我设法创建了一个将src='@Url.CustomContent("~Scripts/my.js")' 转换为src='VirtualPath/Scripts/my.js?&lt;timestamp&gt;' 的扩展方法。您要我在此处添加代码吗?
    猜你喜欢
    • 1970-01-01
    • 2011-01-29
    • 2013-07-14
    • 2012-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-14
    相关资源
    最近更新 更多