基本上我们处于严重的hacky状态。我们有一些链接到其他网站的网页。但是,要求是此站点与链接到我们的站点具有相同的布局。这最初是通过请求原始页面,抓取布局以及在其布局中包装内容来完成的。
这在Web窗体中相当简单,因为我们可以简单地创建一个子类化的页面,它会覆盖Render方法,然后包装我们在外部站点布局中生成的任何内容。但是,现在这个项目正在ASP.NET MVC中重写。
我们怎样才能获得MVC动作创建的HTML结果,根据我们的需要修改它们并将修改后的结果输出到浏览器?
答案 0 :(得分:8)
您可以使用ActionFilterAttribute.OnResultExecuted Method
您可以在此处查看有关ActionFilters的更多示例:
修改强>
关于这个主题有一篇很棒的博客文章:
总结一下,你需要调整你的输出。据我所知,您需要使用RegEx来获取调整完整HTML所需的部分,您可以这样做:
这是助手类:
public class HelperClass : Stream {
//Other Members are not included for brevity
private System.IO.Stream Base;
public HelperClass(System.IO.Stream ResponseStream)
{
if (ResponseStream == null)
throw new ArgumentNullException("ResponseStream");
this.Base = ResponseStream;
}
StringBuilder s = new StringBuilder();
public override void Write(byte[] buffer, int offset, int count) {
string HTML = Encoding.UTF8.GetString(buffer, offset, count);
//In here you need to get the portion out of the full HTML
//You can do that with RegEx as it is explain on the blog pots link I have given
HTML += "<div style=\"color:red;\">Comes from OnResultExecuted method</div>";
buffer = System.Text.Encoding.UTF8.GetBytes(HTML);
this.Base.Write(buffer, 0, buffer.Length);
}
}
这是你过滤的:
public class MyCustomAttribute : ActionFilterAttribute {
public override void OnActionExecuted(ActionExecutedContext filterContext) {
var response = filterContext.HttpContext.Response;
if (response.ContentType == "text/html") {
response.Filter = new HelperClass(response.Filter);
}
}
}
您需要在Global.asax文件Application_Start
方法上注册,如下所示:
protected void Application_Start() {
//there are probably other codes here but I cut them out to stick with point here
GlobalFilters.Filters.Add(new MyCustomAttribute());
}
答案 1 :(得分:2)
在尝试了tugberk的解决方案之后,我最终创建了一个自定义视图结果:
public class WrappedViewResult : ViewResult
{
private readonly object model;
public WrapInDtuViewResult()
{
}
public WrapInDtuViewResult(object model)
{
this.model = model;
}
public override void ExecuteResult(ControllerContext context)
{
if (string.IsNullOrWhiteSpace(this.ViewName))
{
this.ViewName = context.RouteData.Values["action"].ToString();
}
ViewEngineResult result = this.FindView(context);
context.Controller.ViewData.Model = model;
ViewDataDictionary viewData = context.Controller.ViewData;
TempDataDictionary tempData = context.Controller.TempData;
var writer = new StringWriter();
ViewContext viewContext = new ViewContext(context, result.View, viewData, tempData, writer);
result.View.Render(viewContext, writer);
var content = writer.ToString();
Scraping scraping = new Scraping();
if (AppSettings.UseScraping)
{
content = scraping.Render(content);
}
else
{
content = "<html><head><script src='/Scripts/jquery-1.7.1.min.js' type='text/javascript'></script></head><body>" + content + "</body></html>";
}
context.HttpContext.Response.Write(content);
}
}
答案 2 :(得分:1)
使用此博客:
public class OutputCache : ActionFilterAttribute
{
public int Duration { get; set; }
public CachePolicy CachePolicy { get; set; }
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
// Client-side caching?
if (CachePolicy == CachePolicy.Client || CachePolicy == CachePolicy.ClientAndServer)
{
if (Duration <= 0) return;
HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
TimeSpan cacheDuration = TimeSpan.FromSeconds(Duration);
cache.SetCacheability(HttpCacheability.Public);
cache.SetExpires(DateTime.Now.Add(cacheDuration));
cache.SetMaxAge(cacheDuration);
cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
}
}
}