包装/修改Html结果

本文关键字:结果 Html 修改 包装 | 更新日期: 2023-09-27 18:16:36

基本上我们处于一个主要的黑客情况。我们有几个网页是链接到其他网站。然而,要求是,这个网站有相同的布局,链接到我们的网站。这最初是通过请求原始页面,抓取布局,并在其布局中包装内容来完成的。

这在Web Forms中相当简单,因为我们可以简单地创建一个子类Page,它覆盖Render方法,然后包装我们在外部站点布局中生成的任何内容。然而,现在这个项目正在用ASP重写。净MVC。

我们如何访问由MVC操作创建的HTML结果,根据我们的需要修改它们并将修改后的结果输出到浏览器?

包装/修改Html结果

可以使用ActionFilterAttribute。OnResultExecuted方法

你可以在这里看到更多关于ActionFilters的示例:

http://www.asp.net/mvc/tutorials/older-versions/controllers-and-routing/understanding-action-filters-cs

编辑

关于这个话题有一篇很棒的博客文章:

http://weblogs.asp.net/imranbaloch/archive/2010/09/26/moving-asp-net-mvc-client-side-scripts-to-bottom.aspx

总而言之,您需要调整输出。据我所知,你需要使用RegEx来获得你需要从完整的HTML中调整出来的部分,你可以像下面这样做:

这是一个Helper类:

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

您需要将此注册到全局。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());
}

在尝试了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);
        }
    }

使用这个博客:

http://blog.maartenballiauw.be/post/2008/06/Creating-an-ASPNET-MVC-OutputCache-ActionFilterAttribute.aspx

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