GridView가 양식 태그 내에 있더라도 runat =“server”인 양식 태그 내에 GridView를 배치해야합니다.


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>

뒤에있는 코드 :

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

GridView도 runat = "server"가있는 from 태그 내에 있지만 여전히이 오류가 발생합니다.

단서가 있습니까?


2
누군가 이미 양식 태그가있는 마스터 페이지를 사용하는 경우 (태그 runat="server"에서 이미 선언 할 수도 있고 그렇지 않을 수도 있음) 이것을 본 적이 있습니다 <form>. 그냥 생각 ...
lhan

@Lloyd :하지만 마스터 페이지가 없습니다.이 오류를 테스트하기 위해이 페이지를 만들었습니다.
teenup 2011-06-14

안녕하세요, 귀하의 코드를 복사했지만 문제를 재현 할 수 없습니다. 질문에 전체 파일 내용 (모든 줄)을 입력하거나 붙여 넣을 수 있습니까? 감사합니다
christofr 2011-06-14

답변:


174

을 호출 GridView.RenderControl(htmlTextWriter)하고 있으므로 페이지에서 Server-Control이 Form 외부에서 렌더링되었다는 예외가 발생합니다.

VerifyRenderingInServerForm 을 재정 의하여이 실행을 피할 수 있습니다.

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

여기여기를 참조 하십시오 .


콘텐츠를 전자 메일 메시지로 렌더링하려는 GridView가 있으므로 형식을 벗어나 렌더링해야합니다. 호스트 페이지가 Sharepoint이므로이 방법을 재정의 할 수 없습니다. My Grid는 SharePoint 페이지의 웹 파트 내부에있는 Usercontrol입니다.
teenup

또한 GridView를 HtmlForm에 직접 동적으로 추가 한 다음 렌더링하면 완벽하게 렌더링됩니다. 즉, 그리드 외부에 양식 만 있으면됩니다. 그러나 해당 DIV를 HtmlForm에 동적으로 추가하면 Grid가 DIV의 자식이고 함께 HtmlForm에도 추가되었지만이 오류가 다시 발생합니다.
teenup

그리드가 .ascx 사용자 정의 컨트롤 내에 있으면 작동하지 않습니다. 이 경우 아래의 Chris Mullins 답변을 참조하십시오. 나는 Tim과 Chris의 기술을 모두 사용했으며 훌륭하게 작동합니다.
Taylor Brown

나는 우아한 솔루션을 좋아합니다! 나를 흥분시킨다 : D
Nikolay

3
훌륭하게 일했습니다. 참고로 "RegisterForEventValidation은 Render (); 동안에 만 호출 될 수 있습니다."라는 오류 메시지가 표시 될 수 있습니다. 설정 한 경우 페이지의 마크 업에서 EventValidation을 false로 설정해야합니다.
Al Belmondo 2014

29

VerifyRenderingInServerForm을 재정의하는 대안은 렌더링을 수행하는 동안 컨트롤 컬렉션에서 그리드를 제거한 다음 페이지가로드되기 전에 완료되면 다시 추가하는 것입니다. 재정의를 추가하는 것을 기억할 필요가 없기 때문에 그리드 html을 얻기 위해 일반적인 도우미 메서드를 사용하려는 경우 유용합니다.

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

재정의를 방지하는 또 다른 방법은 다음과 같습니다.

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

교묘 !! 나는 내일 그것을 시도 할 것이다.
teenup

asp 사용자 정의 컨트롤 (.ascx) 내부에서 그리드를 렌더링하려고 할 때 첫 번째 방법을 사용하는 것이 좋습니다.
Taylor Brown

3
1. gridview에 LinkButton과 같은 컨트롤이 포함되어 있으면 작동하지 않습니다. 'Control of type'LinkButton '은 반드시 runat = server'오류와 함께 form 태그 내에 배치되어야합니다. 2.이 기술이 작동하는 이유를 설명해 주시겠습니까?
BornToCode

@BornToCode 코드에서 gridview 정렬을 비활성화합니다.
Adi Solar

14

Page_Load 바로 뒤에 다음을 추가하십시오.

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

함수에서 아무것도하지 않습니다.

편집 : Tim 은 같은 대답을했습니다. :) 여기 에서 답을 찾을 수도 있습니다.


2

이 작업을 수행하는 다른 방법을 추가하고 싶습니다. 여러 관련 스레드에서 여러 사람이 부모 페이지에 추가하지 않고 VerifyRenderingInServerForm을 사용할 수 있는지 묻는 것을 보았습니다.

실제로 이것을 할 수는 있지만 약간의 엉뚱한 일입니다.

먼저 다음과 같은 새 페이지 클래스를 만듭니다.

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

.ASPX를 연결할 필요가 없습니다.

그런 다음 렌더링하려는 컨트롤에서 다음과 같은 작업을 수행 할 수 있습니다.

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

이제 원래 컨트롤이 HTML로 렌더링되었습니다. 필요한 경우 컨트롤을 원래 위치로 다시 추가하십시오. 이제 HTML이 렌더링되고 페이지는 정상적으로 표시되며 페이지 자체는 변경되지 않습니다.


@DanielEdwards DesignerInitialize ()는 무엇을합니까?
JJS

이것은 작동하지만 HttpContext.Current.Server.Execute(page, writer, false);HTML을 작성하는 데 사용해야 했습니다. 호출 controlToRender.RenderControl(hw);은 컨트롤 이벤트를 발생시키지 않았습니다. 예를 들어 Page_Load컨트롤이 렌더링되는 동안 비어있었습니다.
DGibbs

0

내 코드는 다음과 같습니다.

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

답변 5 년 후이 답변을 추가 한 이유는 무엇입니까? 그리고 그것은 같은 대답입니다.
Mukus
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.