Câu hỏi GridView phải được đặt bên trong một thẻ biểu mẫu với runat = "server" ngay cả sau khi GridView nằm trong một thẻ biểu mẫu


<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>

Mã ẩn:

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

Ngay cả GridView nằm trong thẻ từ với runat = "server", tôi vẫn nhận được lỗi này.

Có manh mối nào không?


76
2018-06-14 12:41


gốc


Tôi đã thấy điều này trước đây nếu ai đó đang sử dụng trang Chính đã có thẻ biểu mẫu (có thể có hoặc chưa được khai báo runat="server" trong nó <form> nhãn). Chỉ là một ý nghĩ ... - lhan
@Lloyd: Nhưng tôi không có bất kỳ Trang Chính nào, tôi đã tạo trang này để chỉ kiểm tra lỗi này. - teenup
Xin chào, tôi đã sao chép mã của bạn nhưng không thể sao chép vấn đề. Bạn có thể vui lòng đặt toàn bộ nội dung tập tin (mỗi dòng) vào câu hỏi của bạn, hoặc Pastebin nó? Cảm ơn - christofr
có thể trùng lặp GridView phải được thêm vào thẻ biểu mẫu để hiển thị. - Grant Thomas


Các câu trả lời:


Bạn đang gọi GridView.RenderControl(htmlTextWriter), do đó trang này đưa ra một ngoại lệ là một Server-Control được hiển thị bên ngoài một Biểu mẫu.

Bạn có thể tránh việc thực thi này bằng cách ghi đè VerifyRenderingInServerForm

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

Xem đây và đây.


149
2018-06-14 13:01



Tôi có một GridView có nội dung tôi muốn kết xuất vào một Email Message, đó là lý do tại sao tôi cần render nó ra khỏi form. Tôi không thể ghi đè phương thức này vì trang chủ của Sharepoint. My Grid là một Usercontrol bên trong một phần web trong trang sharepoint. - teenup
Ngoài ra, khi tôi thêm GridView đó trực tiếp vào một HtmlForm động, và sau đó render nó, nó hoàn toàn hiển thị. Điều này có nghĩa rằng nó chỉ yêu cầu sự hiện diện của một mẫu bên ngoài lưới điện. Nhưng, khi tôi thêm DIV đó vào HtmlForm động, lỗi này lại xuất hiện, mặc dù Grid là con của DIV và cũng được thêm vào HtmlForm cùng với nó. - teenup
@Tim Schmelter ... bạn là GOD !!! Cảm ơn bạn!! - DotNetRookie
điều này sẽ không hoạt động nếu lưới của bạn nằm trong một điều khiển người dùng .ascx. trong trường hợp đó, hãy xem Chris Mullins trả lời dưới đây. Tôi đã sử dụng cả hai kỹ thuật của Tim và Chris và chúng hoạt động rất tốt. - Taylor Brown
Làm việc tuyệt vời. Chỉ cần một người đứng đầu lên bạn có thể nhận được một lỗi nói rằng "RegisterForEventValidation chỉ có thể được gọi trong Render ();" Nếu được đặt, hãy đảm bảo đặt EventValidation thành false trong đánh dấu cho trang. - Al Belmondo


Một thay thế để ghi đè VerifyRenderingInServerForm là để loại bỏ lưới từ bộ sưu tập điều khiển trong khi bạn thực hiện kết xuất, và sau đó thêm nó trở lại khi bạn hoàn tất trước khi tải trang. Điều này rất hữu ích nếu bạn muốn có một số phương thức trợ giúp chung để nhận html lưới vì bạn không phải nhớ thêm ghi đè.

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

Một cách khác để tránh ghi đè là thực hiện việc này:

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



Adroit !! Tôi sẽ thử nó vào ngày mai. - teenup
khi cố gắng để render lưới bên trong một điều khiển người dùng asp (.ascx), bằng cách sử dụng phương pháp 1 làm việc tuyệt vời cho tôi. - Taylor Brown
1.Nó không hoạt động nếu GridView chứa các điều khiển như LinkButton - nó cho phép 'Điều khiển kiểu' LinkButton 'phải được đặt bên trong một thẻ biểu mẫu với lỗi runat = server'. 2.Bạn có thể giải thích tại sao kỹ thuật này hoạt động? - BornToCode
@BornToCode Vô hiệu hóa sắp xếp cho GridView của bạn trong mã. - Adi Solar
vô hiệu hóa phân loại và phân trang không hoạt động - Vani


Ngay sau khi Page_Load của bạn thêm điều này:

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

Lưu ý rằng tôi không làm bất cứ điều gì trong chức năng.

CHỈNH SỬA: Tim trả lời cùng một điều. :) Bạn cũng có thể tìm câu trả lời Đây


11
2018-06-14 13:02





Chỉ muốn thêm một cách khác để làm điều này. Tôi đã nhìn thấy nhiều người trên các chủ đề liên quan khác nhau hỏi bạn có thể sử dụng VerifyRenderingInServerForm mà không cần thêm nó vào trang mẹ hay không.

Bạn thực sự có thể làm điều này nhưng nó là một chút của một nhà nghỉ.

Trước tiên, tạo một lớp Trang mới trông giống như sau:

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

Không cần phải có .ASPX liên kết với nó.

Sau đó, trong điều khiển bạn muốn hiển thị, bạn có thể làm điều gì đó như sau.

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

Bây giờ bạn đã có quyền kiểm soát ban đầu được hiển thị dưới dạng HTML. Nếu bạn cần, hãy thêm điều khiển trở lại vị trí ban đầu của nó. Bây giờ bạn có HTML được hiển thị, trang như bình thường và không có thay đổi nào đối với trang đó.


1
2018-02-23 15:52



Cách quá nhiều mã để đạt được một cái gì đó đơn giản. - SearchForKnowledge
@DanielEdwards DesignerInitialize () làm gì cho bạn? - JJS


Đây là Mã của tôi

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



Tại sao bạn thêm câu trả lời này 5 năm sau khi câu trả lời được trả lời? Và đó là câu trả lời tương tự. - Mukus