我需要拦截将发送到浏览器的所有html并替换那里的一些标签。这需要在全球范围内和每个视图中完成。使用C#在ASP.NET MVC 3或4中执行此操作的最佳方法是什么?在过去,我使用Global.asax(vb)中的'response.filter'在ASP.net Webforms中完成了此操作
Private Sub Global_PreRequestHandlerExecute(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PreRequestHandlerExecute
Response.Filter = New ReplaceTags(Response.Filter)
End Sub
这会调用我创建的一个继承自system.io.stream的类,并通过html来替换所有标记。 我不知道如何使用C#在ASP.NET MVC 4中执行此操作。你可能已经注意到我在MVC世界中是一个全新的人。
答案 0 :(得分:9)
您仍然可以在ASP.NET MVC中使用响应过滤器:
public class ReplaceTagsFilter : MemoryStream
{
private readonly Stream _response;
public ReplaceTagsFilter(Stream response)
{
_response = response;
}
public override void Write(byte[] buffer, int offset, int count)
{
var html = Encoding.UTF8.GetString(buffer);
html = ReplaceTags(html);
buffer = Encoding.UTF8.GetBytes(html);
_response.Write(buffer, offset, buffer.Length);
}
private string ReplaceTags(string html)
{
// TODO: go ahead and implement the filtering logic
throw new NotImplementedException();
}
}
然后编写一个自定义操作过滤器,它将注册响应过滤器:
public class ReplaceTagsAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var response = filterContext.HttpContext.Response;
response.Filter = new ReplaceTagsFilter(response.Filter);
}
}
现在剩下的就是装饰你想要应用这个过滤器的控制器/动作:
[ReplaceTags]
public ActionResult Index()
{
return View();
}
如果要应用于所有操作,请将其注册为Global.asax中的全局操作过滤器。
答案 1 :(得分:5)
答案是正确的但是。在使用它一段时间后,我遇到了一个案例,当响应被分成很多部分,因此html不正确
Part 1:
<html>.....<labe
Part 2:
l/>...</html>
部分渲染也可能会出现意外情况。他们的HTML也不在主流中。 所以我的解决方案是在完成所有流式传输后在Flush方法中完成。
/// <summary>
/// Insert messages and script to display on client when a partial view is returned
/// </summary>
private class ResponseFilter : MemoryStream
{
private readonly Stream _response;
private readonly IList<object> _detachMessages;
public override void Flush()
{
// add messages and remove
// filter is called for a number of methods on one page (BeginForm, RenderPartial...)
// so that we don't need to add it more than once
var html = MessageAndScript(_detachMessages);
var buffer = Encoding.UTF8.GetBytes(html);
_detachMessages.Clear();
_response.Write(buffer, 0, buffer.Length);
base.Flush();
}
public ResponseFilter(Stream response, IList<object> detachMessages)
{
_response = response;
_detachMessages = detachMessages;
}
public override void Write(byte[] buffer, int offset, int count)
{
_response.Write(buffer, offset, buffer.Length);
}
private static string MessageAndScript(IList<object> detachMessages)
{
if (detachMessages.Count == 0)
return null;
var javascript = CustomJavaScriptSerializer.Instance.Serialize(detachMessages);
return "$(function(){var messages = " + javascript + @";
// display messages
base.ajaxHelper.displayMessages(messages);
})";
}
}