如何使用ASP.NET MVC ActionFilter替换呈现的HTML中的URL

Kel*_*tex 3 asp.net-mvc action-filter

我正在尝试创建一个ActionFilter来替换HTML中的一些文本.基本上当服务器使用SSL时,我希望将对我的CDN(http://cdn.example.com)的引用替换为直接引用到我的服务器(https://www.example.com).所以结构是这样的(我假设OnResultExecuted是我应该开始的地方):

public class CdnSslAttribute : ActionFilterAttribute
{
    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        if(filterContext.HttpContext.Request.IsSecureConnection)
        {
            // when the connection is secure,
            // somehow replace all instances of http://cdn.example.com
            // with https://www.example.com
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这将用于我的安全控制器:

[CdnSsl] 
public class SecureController : Controller
{
}
Run Code Online (Sandbox Code Playgroud)

我想这样做的原因是我的CDN不支持SSL.并且Master页面中有对CDN资源的引用.例:

<link href="http://cdn.example.com/Content/base.css" rel="stylesheet" type="text/css" />
Run Code Online (Sandbox Code Playgroud)

Kel*_*tex 5

我最后在这篇博客文章中使用了一个变体:

http://arranmaclean.wordpress.com/2010/08/10/minify-html-with-net-mvc-actionfilter/

用我自己的过滤器:

public class CdnSslAttribute : ActionFilterAttribute
{
    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsSecureConnection)
        {
            var response = filterContext.HttpContext.Response;
            response.Filter = new CdnSslFilter(response.Filter);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后过滤器看起来像这样(为简洁起见省略了一些代码):

public class CdnSslFilter : Stream
{
    private Stream _shrink;
    private Func<string, string> _filter;

    public CdnSslFilter(Stream shrink)
    {
        _shrink = shrink;
        _filter = s => Regex.Replace(s,@"http://cdn\.","https://www.", RegexOptions.IgnoreCase);
    }

    //overridden functions omitted for clarity. See above blog post.

    public override void Write(byte[] buffer, int offset, int count)
    {
        // capture the data and convert to string 
        byte[] data = new byte[count];
        Buffer.BlockCopy(buffer, offset, data, 0, count);
        string s = Encoding.Default.GetString(buffer);

        // filter the string
        s = _filter(s);

        // write the data to stream 
        byte[] outdata = Encoding.Default.GetBytes(s);
        _shrink.Write(outdata, 0, outdata.GetLength(0));
    }
}
Run Code Online (Sandbox Code Playgroud)