Подтвердить что ты не робот

UserControl RenderControl запрашивает тег формы в (С#.NET)

Я спросил как отобразить HTML-код UserControl и получил код, работающий для динамически созданного UserControl.

Теперь я пытаюсь использовать LoadControl для загрузки ранее созданного элемента управления и выплевывать его 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();
4b9b3361

Ответ 1

В качестве альтернативы вы можете отключить проверку ServerForm/Event на странице, которая передает элемент управления в строку.

В следующем примере показано, как это сделать.

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 */}
    }
}

Ответ 2

Вы можете добавить элемент управления на страницу, отобразить html, а затем удалить элемент управления со страницы.

Или попробуйте следующее:

Page tmpPage = new TempPage(); // temporary page
Control tmpCtl = tmpPage.LoadControl( "~/UDynamicLogin.ascx" );
//the Form is null that 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 );
    }
}

Ответ 3

Это грязное решение, которое я использовал на данный момент (заставить его работать, затем правильно, верно?).

Я уже создал новый класс, который наследует класс UserControl и из которого были созданы все другие "UserControls", которые я создал. Я назвал его formPartial (nod to Rails), и это происходит внутри метода public render 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();

Отклонения от верхней части головы:

  • Вам нужно выражение о делах с каждым возможный контроль (или контролирует вас ожидать).
  • Вам необходимо перенести все   важные атрибуты из   существующий контроль (текстовое поле и т.д.) до   новый пустой контроль.
  • Не в полной мере использовать преимущества Метод управления RenderControl.

Было бы легко испортить 1 или 2. Надеюсь, это поможет кому-то придумать более элегантное решение.

Ответ 4

Вы можете либо добавить форму в свой пользовательский элемент управления, либо использовать регулярное поле ввода 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();
    }

Вы можете удалить часть привязки данных, если это не требуется.

Ответ 5

У меня была такая же проблема с использованием аналогичного кода для @TcKs, и я не смог заставить любой из этих примеров работать для меня. Я получил его, используя метод LoadControl UserControl как таковой:

UserControl uc = new UserControl();
Control c = uc.LoadControl("newUserControl.ascx");
c.RenderControl(myWriter);