我正在尝试实现这个例子:
但是我的 ASP.NET MVC4 应用程序Filtering is not allowed
在代码行上的第一个 Action 异常消息之后执行任何操作时都会抛出异常filterContext.RequestContext.HttpContext.Response.Filter = new CdnResponseFilter(filterContext.RequestContext.HttpContext.Response.Filter);
。
基于一些搜索,我尝试将过滤器移动到另一个事件函数,但它们都没有奏效。我还尝试检查过滤器是否已应用,如果是,请不要添加新过滤器。
第一个动作被正确过滤,它在执行第二个动作时引发异常。
代码
public class CDNUrlFilter : IActionFilter, IResultFilter
{
public void OnActionExecuting(ActionExecutingContext filterContext)
{
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
filterContext.RequestContext.HttpContext.Response.Filter = new CdnResponseFilter(filterContext.RequestContext.HttpContext.Response.Filter);
}
public void OnResultExecuting(ResultExecutingContext filterContext)
{
}
public void OnResultExecuted(ResultExecutedContext filterContext)
{
}
}
public class CdnResponseFilter : MemoryStream
{
private Stream Stream { get; set; }
public CdnResponseFilter(Stream stream)
{
Stream = stream;
}
public override void Write(byte[] buffer, int offset, int count)
{
var data = new byte[count];
Buffer.BlockCopy(buffer, offset, data, 0, count);
string html = Encoding.Default.GetString(buffer);
html = Regex.Replace(html, "src=\"/Content/([^\"]+)\"", FixUrl, RegexOptions.IgnoreCase);
html = Regex.Replace(html, "href=\"/Content/([^\"]+)\"", FixUrl, RegexOptions.IgnoreCase);
html = Regex.Replace(html, "src=\"/Images/([^\"]+)\"", FixUrl, RegexOptions.IgnoreCase);
html = Regex.Replace(html, "href=\"/Images/([^\"]+)\"", FixUrl, RegexOptions.IgnoreCase);
byte[] outData = Encoding.Default.GetBytes(html);
Stream.Write(outData, 0, outData.GetLength(0));
}
private static string FixUrl(Match match)
{
if (match.ToString().Contains("src"))
{
return String.Format("{0}", match.ToString());
}
else if (match.ToString().Contains("href"))
{
return String.Format("href=\"{0}content{1}", Settings.Default.CDNDomain, match.ToString().Replace("href=\"", ""));
}
return match.ToString();
}
}
这里要求的是从 Global.asax.cs 调用的 RegisterGlobalFilters:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new Filters.InitializeSimpleMembershipAttribute());
filters.Add(new Filters.RequestTimingFilter());
if (Settings.Default.CDNEnable)
{
filters.Add(new Filters.CDNUrlFilter());
}
}
}
添加完整堆栈跟踪的另一个编辑:
Stack Trace
at System.Web.HttpResponse.set_Filter(Stream value)
at POSGuys.Filters.CDNUrlFilter.OnActionExecuted(ActionExecutedContext filterContext) in c:\Users\skatir\Documents\BitBucket\posguys\Filters\CDNUrlFilter.cs:line 20
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass4f.b__49()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass4f.b__49()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass4f.b__49()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass37.b__36(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass25.<>c__DisplayClass2a.b__20()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass25.b__22(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.<>c__DisplayClass1d.b__18(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass4.b__3(IAsyncResult ar)
at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass4.b__3(IAsyncResult ar)
at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.<>c__DisplayClass8.b__3(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass4.b__3(IAsyncResult ar)
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
at System.Web.Mvc.HttpHandlerUtil.ServerExecuteHttpHandlerWrapper.<>c__DisplayClass4.b__3()
at System.Web.Mvc.HttpHandlerUtil.ServerExecuteHttpHandlerWrapper.Wrap[TResult](Func`1 func)
at System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride)
Target Site
Void set_Filter(System.IO.Stream)
在尝试解决这个问题时,我偶然发现了一些非常奇怪的事情,那就是如果我将 OnActionExecute 中的 Response.Filter 的设置包装在 try{}catch{} 中,会阻止页面正确使用过滤器呈现。这让我觉得系统的其他一些部分被尝试过滤掉,而不应该过滤掉。我将在调试器中做一些工作,看看我是否不能从这里缩小范围。