ASP.NET如何将控件呈现为HTML?

31

我有一个ASP.NET控件,我想获取它的HTML字符串,应该如何实现?

3个回答

44

这似乎正常工作。

public string RenderControlToHtml(Control ControlToRender)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    System.IO.StringWriter stWriter = new System.IO.StringWriter(sb);
    System.Web.UI.HtmlTextWriter htmlWriter = new System.Web.UI.HtmlTextWriter(stWriter);
    ControlToRender.RenderControl(htmlWriter);
    return sb.ToString();
}

7
StringWriter 和 HtmlTextWriter 都实现了 IDisposable 接口,所以你可能想要将它们放入 using() {} 代码块中。此外,将其作为 'Control' 的扩展方法可能很有用,这样你就可以从实例成员中调用它。 - Joe Blazek
1
@David,你是怎么把ascx文件渲染成html的?我试过上面的方法,但总是出现“对象引用未设置为对象实例”的错误,说我引用的用户控件不是一个实例。我们应该如何在Windows窗体或控制台应用程序中使用它? - Princa
1
默认的StringWriter()构造函数创建一个新的字符串构建器,因此前两行可以替换为System.IO.StringWriter stWriter = new System.IO.StringWriter();。 - Spongeboy
这总是给我一个空字符串。然而,a7drew的解决方案像魅力一样奏效。 - Tillito
我将新的 Controls.sidebar() 传递给函数,但是我得到了空字符串,尽管在内联运行时控件呈现 HTML。 - Liron Harel
除非控件是页面的一部分,否则这将无法工作。 - avs099

15

如果控件不是页面的一部分,那么David Basarab所提供的答案将无法工作。a7drew的答案似乎过于复杂- 不需要使用ContextServer.Execute

private string RenderControl()
{
    var sb = new System.Text.StringBuilder();
    using (var stWriter = new System.IO.StringWriter(sb))
    using (var htmlWriter = new HtmlTextWriter(stWriter))
    {
        var p = new Page();
        var ctrl = (YourControl)p.LoadControl("~/controls/building blocks/YourControl.ascx");
        ctrl.Visible = true;

        // do your own init logic if needed

        p.Controls.Add(ctrl);
        ctrl.RenderControl(htmlWriter);
        return sb.ToString();
    }
}

谢谢,这个好使!顺便说一句,在我的测试中,好像不需要 ctrl.Visible = true; 这一行。 - Otto G
谢谢!我有一个方法,它在服务中可行,但在从 API 调用时不可行。这个方法可以工作! - Adam Mendoza
我认为 ctrl.Visible = true; 是一种保险措施。在我的情况下,控件在标记中设置了 @Visible="false"@,导致它呈现为空字符串。 - liviriniu

6

如果您的控件是Web用户控件,那么您可以通过以下方式从另一个页面或处理程序获取其发出的HTML:

public void GetHtmlFromMySweetControl(HttpContext context)
{
    HttpRequest httpRequest = context.Request;
    HttpResponse httpResponse = context.Response;

    string foo = httpRequest["foo"];

    Page pageHolder = new Page();
    string path = "~/usercontrols/MySweetControl.ascx";
    MySweetControl ctrl = (MySweetControl)pageHolder.LoadControl(path);
    ctrl.BindProducts(foo);
    pageHolder.Controls.Add(ctrl);

    StringWriter sw = new StringWriter();
    context.Server.Execute(pageHolder, sw, false);
    httpResponse.Write(sw.ToString());
}

当我尝试这样做时,呈现的HTML与页面上通常显示的不同。例如,带有GroupingText属性的asp:Panel。GroupingText属性的值现在呈现为一个fieldset和legend。这是不可取的...就像UserControl正在以某种不同的模式下呈现一样...完全不同的HTML...:( - ClearCloud8
太好了!我甚至不知道这是可能的!这允许非常有效的缓存内容方式!非常感谢! - Tillito

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接