UserControl的RenderControl要求(C#.NET)中的表单标记

问题描述 投票:12回答:5

我问how to render a UserControl's HTML并获得了动态生成的UserControl的代码。

现在我正在尝试使用LoadControl来加载以前生成的Control并吐出它的HTML,但它给了我这个:

必须将带有'TextBox'类型的控件放在带有runat = server的表单标记内。

我实际上并没有将控件添加到页面中,我只是想抓取它的HTML。有任何想法吗?

这是我正在玩的一些代码:

TextWriter myTextWriter = new StringWriter();
HtmlTextWriter myWriter = new HtmlTextWriter(myTextWriter);

UserControl myControl = (UserControl)LoadControl("newUserControl.ascx");
myControl.RenderControl(myWriter);

return myTextWriter.ToString();
c# html .net user-controls
5个回答
16
投票

或者,您可以在将控件呈现为字符串的页面上禁用ServerForm / Event-validation。

以下示例说明了如何执行此操作。

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string rawHtml = RenderUserControlToString();
    }

    private string RenderUserControlToString()
    {
        UserControl myControl = (UserControl)LoadControl("WebUserControl1.ascx");

        using (TextWriter myTextWriter = new StringWriter())
        using (HtmlTextWriter myWriter = new HtmlTextWriter(myTextWriter))
        {
            myControl.RenderControl(myWriter);

            return myTextWriter.ToString();
        }
    }

    public override void VerifyRenderingInServerForm(Control control)
    { /* Do nothing */ }

    public override bool EnableEventValidation
    {
        get { return false; }
        set { /* Do nothing */}
    }
}

1
投票

这是我目前使用的一个肮脏的解决方案(让它工作,然后把它弄好,对吧?)。

我已经创建了一个继承UserControl类的新类,并且从中创建了我创建的所有其他“UserControls”。我把它称为formPartial(向Rails点头),这是在公共字符串renderMyHTML()方法内部:

TextWriter myTextWriter = new StringWriter();
HtmlTextWriter myWriter = new HtmlTextWriter(myTextWriter);

UserControl myDuplicate = new UserControl();
TextBox blankTextBox;

foreach (Control tmpControl in this.Controls)
{
    switch (tmpControl.GetType().ToString())
    {
        case "System.Web.UI.LiteralControl":
            blankLiteral = new LiteralControl();
            blankLiteral.Text = ((LiteralControl)tmpControl).Text;
            myDuplicate.Controls.Add(blankLiteral);
            break;
        case "System.Web.UI.WebControls.TextBox":
            blankTextBox = new TextBox();
            blankTextBox.ID = ((TextBox)tmpControl).ID;
            blankTextBox.Text = ((TextBox)tmpControl).Text;
            myDuplicate.Controls.Add(blankTextBox);
            break;

            // ...other types of controls (ddls, checkboxes, etc.)

    }
}

myDuplicate.RenderControl(myWriter);
return myTextWriter.ToString();

脱离我的头脑:

  1. 您需要一个包含所有可能控件(或您期望的控件)的case语句。
  2. 您需要将现有控件(文本框等)中的所有重要属性传输到新的空白控件。
  3. 没有充分利用Controls的RenderControl方法。

很容易弄乱1或2.但是,希望这可以帮助其他人提出更优雅的解决方案。


1
投票

您可以将控件添加到页面,渲染html,然后从页面中删除控件。

或试试这个:

Page tmpPage = new TempPage(); // temporary page
Control tmpCtl = tmpPage.LoadControl( "~/UDynamicLogin.ascx" );
//the Form is null that's throws an exception
tmpPage.Form.Controls.Add( tmpCtl );

StringBuilder html = new StringBuilder();
using ( System.IO.StringWriter swr = new System.IO.StringWriter( html ) ) {
    using ( HtmlTextWriter writer = new HtmlTextWriter( swr ) ) {
        tmpPage.RenderControl( writer );
    }
}

0
投票

您可以将表单添加到用户控件,也可以使用常规的html输入框

 <input type="text" />

编辑:如果你正在尝试做一些AJAXy,也许你想要像这样的http://aspadvice.com/blogs/ssmith/archive/2007/10/19/Render-User-Control-as-String-Template.aspx

    public static string RenderView<D>(string path, D dataToBind)
    {
        Page pageHolder = new Page();
        UserControl viewControl = (UserControl) pageHolder.LoadControl(path);
        if(viewControl is IRenderable<D>)
        {
            if (dataToBind != null)
            {
                ((IRenderable<D>) viewControl).PopulateData(dataToBind);
            }
        }
        pageHolder.Controls.Add(viewControl);
        StringWriter output = new StringWriter();
        HttpContext.Current.Server.Execute(pageHolder, output, false);

        return output.ToString();
    }

如果不需要,您可以删除数据绑定部分。


-1
投票

我使用与@TcKs类似的代码遇到了同样的问题,并且无法使这些示例中的任何一个对我有用。我通过使用LoadControlUserControl方法得到它的工作原理:

UserControl uc = new UserControl();
Control c = uc.LoadControl("newUserControl.ascx");
c.RenderControl(myWriter);
© www.soinside.com 2019 - 2024. All rights reserved.