GridView phải được đặt bên trong thẻ biểu mẫu với runat = “server” ngay cả sau khi GridView nằm trong thẻ biểu mẫu


86
<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ả khi GridView nằm trong thẻ from với runat = "server", tôi vẫn gặp lỗi này.

Bất kỳ manh mối xin vui lòng?


2
Tôi đã từng 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 có thể chưa khai báo runat="server"trong <form>thẻ của nó ). Chỉ là một suy nghĩ ...
— lhan

@Lloyd: Nhưng tôi không có Trang Chính nào cả, 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ể tái tạo sự cố. Bạn có thể vui lòng đưa toàn bộ nội dung tệp (mỗi dòng) vào câu hỏi của bạn, hoặc Pastebin nó? Cảm ơn
— christofr

Câu trả lời:


174

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

Bạn có thể tránh 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 .


Tôi có một GridView có nội dung tôi muốn hiển thị thành Thư Email, đó là lý do tại sao tôi cần hiển thị nó dưới dạng. Tôi không thể ghi đè phương pháp này vì trang chủ là 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 HtmlForm động và sau đó kết xuất nó, nó sẽ hiển thị hoàn hảo. Điều này có nghĩa là nó chỉ yêu cầu sự hiện diện của một biểu mẫu bên ngoài lưới. 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

điều này sẽ không hoạt động nếu lưới của bạn nằm trong kiểm soát của người dùng .ascx. trong trường hợp đó, hãy xem câu trả lời của Chris Mullins bên dưới. Tôi đã sử dụng cả kỹ thuật của Tim và Chris và chúng hoạt động rất tốt.
— Taylor Brown

Tôi thích một giải pháp thanh lịch! Làm tôi phấn khích: D
— Nikolay

3
Làm việc rất tốt. Chỉ cần lưu ý, bạn có thể gặp lỗi "RegisterForEventValidation chỉ có thể được gọi trong khi Render ();" Nếu được đặt như vậy, hãy đảm bảo đặt EventValidation thành false trong phần đánh dấu cho trang.
— Al Belmondo

29

Một giải pháp thay thế cho việc ghi đè VerifyRenderingInServerForm là xóa lưới khỏi bộ sưu tập điều khiển trong khi bạn thực hiện kết xuất, sau đó thêm lại lưới khi bạn hoàn thành 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 pháp trợ giúp chung để lấy 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 điều 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);

Khéo léo!! Tôi sẽ thử nó vào ngày mai.
— teenup

khi cố gắng hiển thị lưới bên trong điều khiển người dùng asp (.ascx), sử dụng phương pháp thứ nhất rất hiệu quả đối với tôi.
— Taylor Brown,

3
1. Nó không hoạt động nếu gridview chứa các điều khiển như LinkButton - nó cung cấp 'Điều khiển loại' LinkButton 'phải được đặt bên trong thẻ biểu mẫu có lỗi runat = server'. 2. Bạn có thể vui lòng 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 chế độ xem lưới của bạn trong mã.
— Adi Solar

14

Ngay sau khi Trang_Load của bạn thêm cái 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 hàm.

CHỈNH SỬA: Tim đã trả lời điều tương tự. :) Bạn cũng có thể tìm thấy câu trả lời Tại đây


2

Chỉ muốn thêm một cách khác để làm điều này. Tôi đã thấy nhiều người trên các chủ đề liên quan khác nhau hỏi liệu 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ó hơi khó khăn.

Trước hết, hãy 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 được liên kết với nó.

Sau đó, trong điều khiển mà bạn muốn kết xuất, bạn có thể làm 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ó điều khiển ban đầu của mình đượ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. Bây giờ bạn đã hiển thị HTML, trang như bình thường và không có thay đổi nào đối với chính trang đó.


@DanielEdwards DesignerInitialize () làm được gì cho bạn?
— JJS

Điều này hoạt động nhưng tôi cần sử dụng HttpContext.Current.Server.Execute(page, writer, false);để viết HTML - việc gọi controlToRender.RenderControl(hw);không nâng cao bất kỳ sự kiện điều khiển nào, ví dụ, Page_Loadvì vậy trong khi điều khiển đang hiển thị, nó trống.
— DGibbs

0

Đâ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. */
    }

Tại sao bạn lại thêm câu trả lời này vào 5 năm sau khi nó được trả lời? Và nó là cùng một câu trả lời.
— Mukus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookie và Chính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.