Pytanie GridView musi być umieszczony wewnątrz tagu formularza z runat = "server", nawet jeśli GridView znajduje się w tagu formularza


<form runat="server" id="f1">
    <div runat="server" id="d">
        grid view:
        <asp:GridView runat="server" ID="g">
        </asp:GridView>
    </div>

    <asp:TextBox runat="server" ID="t" TextMode="MultiLine" Rows="20" Columns="50"></asp:TextBox>
</form>

Kod za:

public partial class ScriptTest : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        g.DataSource = new string[] { "a", "b", "c" };
        g.DataBind();

        TextWriter tw = new StringWriter();
        HtmlTextWriter h = new HtmlTextWriter(tw);    
        d.RenderControl(h);
        t.Text = tw.ToString();
    }
}

Nawet GridView znajduje się w tagu from z runat = "server", nadal otrzymuję ten błąd.

Jakieś wskazówki?


76
2018-06-14 12:41


pochodzenie


Widziałem to już wcześniej, jeśli ktoś używa strony wzorcowej, która ma już znacznik formularza (który może, ale nie musi, deklarować runat="server" w tym jest <form> etykietka). Tylko myśl ... - lhan
@Lloyd: Ale nie mam żadnej strony wzorcowej, utworzyłem tę stronę tylko do testowania tego błędu. - teenup
Cześć! Skopiowałem twój kod, ale nie mogę zreplikować problemu. Czy możesz umieścić całą treść pliku (każdą linię) na swoim pytaniu, lub Pastebin to? Dzięki - christofr
możliwy duplikat GridView należy dodać do znacznika formularza do renderowania. - Grant Thomas


Odpowiedzi:


Dzwonisz GridView.RenderControl(htmlTextWriter), stąd strona wywołuje wyjątek, że kontrola serwera została wykonana poza formularzem.

Możesz tego uniknąć przez przesłonięcie VerifyRenderingInServerForm

public override void VerifyRenderingInServerForm(Control control)
{
  /* Confirms that an HtmlForm control is rendered for the specified ASP.NET
     server control at run time. */
}

Widzieć tutaj i tutaj.


149
2018-06-14 13:01



Mam GridView, którego zawartość chcę renderować w wiadomości e-mail, dlatego muszę renderować go z formularza. Nie mogę przesłonić tej metody, ponieważ strona hosta zawiera SharePoint. My Grid to UserControl w części strony internetowej na stronie SharePoint. - teenup
Ponadto, gdy dodaję GridView bezpośrednio do HtmlForm dynamicznie, a następnie renderuję go, to on doskonale renderuje. Oznacza to, że wymaga tylko obecności formularza poza siatką. Ale kiedy dynamicznie dodaję DIV do HtmlForm, ten błąd pojawia się ponownie, chociaż Grid jest dzieckiem DIV, a także dodane do HtmlForm razem z nim. - teenup
@Tim Schmelter ... jesteś BOGIEM !!! Dziękuję Ci!! - DotNetRookie
to nie zadziała, jeśli twoja siatka znajduje się wewnątrz formantu użytkownika .ascx. w takim przypadku zobacz odpowiedź Chrisa Mullins'a poniżej. Użyłem zarówno technik Tima, jak i Chrisa, i działają świetnie. - Taylor Brown
Pracował świetnie. Po prostu heads-up może pojawić się błąd "RegisterForEventValidation można wywołać tylko podczas Renderowania ();" Jeśli tak, ustaw wartość EventValidation na false w znaczniku dla strony. - Al Belmondo


Alternatywą do przesłonięcia VerifyRenderingInServerForm jest usunięcie siatki z kolekcji kontrolek podczas renderowania, a następnie dodanie jej ponownie po zakończeniu ładowania strony. Jest to przydatne, jeśli chcesz mieć jakąś ogólną metodę pomocnika, aby uzyskać html siatki, ponieważ nie musisz pamiętać o dodaniu zastąpienia.

Control parent = grid.Parent;
int GridIndex = 0;
if (parent != null)
{
    GridIndex = parent.Controls.IndexOf(grid);
    parent.Controls.Remove(grid);
}

grid.RenderControl(hw);

if (parent != null)
{
    parent.Controls.AddAt(GridIndex, grid);
}

Inną alternatywą pozwalającą uniknąć nadpisania jest wykonanie tego:

grid.RenderBeginTag(hw);
grid.HeaderRow.RenderControl(hw);
foreach (GridViewRow row in grid.Rows)
{
    row.RenderControl(hw);
}
grid.FooterRow.RenderControl(hw);
grid.RenderEndTag(hw);

26
2018-06-14 14:19



Zręczny!! Spróbuję tego jutro. - teenup
podczas próby renderowania siatki wewnątrz formantu użytkownika asp (.ascx), pierwsza metoda zadziałała dla mnie świetnie. - Taylor Brown
1. To nie działa, jeśli gridview zawiera kontrolki takie jak LinkButton - daje to "Control of type" LinkButton "musi być umieszczony wewnątrz tagu formularza z błędem runat = server". 2. Czy mógłbyś wyjaśnić, dlaczego ta technika działa? - BornToCode
@BornToCode Wyłącz sortowanie dla widoku siatki w kodzie. - Adi Solar
wyłączenie sortowania i stronicowania nie działa - Vani


Zaraz po dodaniu strony Page_Load:

public override void VerifyRenderingInServerForm(Control control)
{
    //base.VerifyRenderingInServerForm(control);
}

Zauważ, że nic nie robię w funkcji.

EDYTOWAĆ: Tim odpowiedział na to samo. :) Możesz również znaleźć odpowiedź Tutaj


11
2018-06-14 13:02





Po prostu chcę dodać inny sposób robienia tego. Widziałem wiele osób na różnych powiązanych wątkach, zapytaj, czy możesz użyć VerifyRenderingInServerForm bez dodawania go do strony nadrzędnej.

Możesz to zrobić, ale to trochę bodge.

Najpierw utwórz nową klasę strony, która wygląda mniej więcej tak:

public partial class NoRenderPage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    { }

    public override void VerifyRenderingInServerForm(Control control)
    {
        //Allows for printing
    }

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

Nie musi być powiązany z .ASPX.

Następnie w formancie, który chcesz renderować, możesz zrobić coś takiego.

    StringWriter tw = new StringWriter();
    HtmlTextWriter hw = new HtmlTextWriter(tw);

    var page = new NoRenderPage();
    page.DesignerInitialize();
    var form = new HtmlForm();
    page.Controls.Add(form);
    form.Controls.Add(pnl);
    controlToRender.RenderControl(hw);

Teraz masz oryginalną kontrolę renderowaną jako HTML. Jeśli musisz, dodaj kontrolkę z powrotem do oryginalnej pozycji. Teraz renderowany jest HTML, strona normalna i żadna zmiana samej strony.


1
2018-02-23 15:52



Zbyt wiele kodu, aby osiągnąć coś prostego. - SearchForKnowledge
@DanielEdwards co robi dla ciebie DesignerInitialize ()? - JJS


Oto mój kod

protected void btnExcel_Click(object sender, ImageClickEventArgs e)
    {
        if (gvDetail.Rows.Count > 0)
        {
            System.IO.StringWriter stringWrite1 = new System.IO.StringWriter();
            System.Web.UI.HtmlTextWriter htmlWrite1 = new HtmlTextWriter(stringWrite1);
            gvDetail.RenderControl(htmlWrite1);

            gvDetail.AllowPaging = false;
            Search();
            sh.ExportToExcel(gvDetail, "Report");
        }
    }

    public override void VerifyRenderingInServerForm(Control control)
    {
        /* Confirms that an HtmlForm control is rendered for the specified ASP.NET
           server control at run time. */
    }

1
2017-09-02 12:56



Dlaczego dodałeś tę odpowiedź 5 lat po otrzymaniu odpowiedzi? I to jest ta sama odpowiedź. - Mukus