ASP.NET 4.0 GridView OnRowEditing events not firing when using Unity 2.0 http module

扶醉桌前 提交于 2019-12-07 12:43:34

问题


I have an ASP.NET web forms site using Master Pages. It is using Unity as my IoC container. I have created an HTTP Module to build up the container using a couple of tutorials i found online. I need the dependency injection to work for User Controls and the only way i was able to get this to work was to hook into the Pages PreInit event as can be seen from the code below.

public class UnityHttpModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.PreRequestHandlerExecute += OnPreRequestHandlerExecute;
    }

    public void Dispose() { }

    private void OnPreRequestHandlerExecute(object sender, EventArgs e)
    {
        IHttpHandler currentHandler = HttpContext.Current.Handler;
        HttpContext.Current.Application.GetContainer().BuildUp(
                            currentHandler.GetType(), currentHandler);

        // User Controls are ready to be built up after page initialization is complete
        var currentPage = HttpContext.Current.Handler as Page;
        if (currentPage != null)
        {
            currentPage.PreInit += Page_PreInit;
        }
    }

    // Build up each control in the page's control tree
    private void Page_PreInit(object sender, EventArgs e)
    {
        var currentPage = (Page)sender;

        BuildUp(currentPage);

        BuildUpMaster(currentPage.Master);

        BuildUpControls(currentPage.Controls);
    }


    private void BuildUp(object o)
    {
        HttpContext.Current.Application.GetContainer().BuildUp(o.GetType(), o);
    }

    private void BuildUpControls(ControlCollection controls)
    {
        foreach (Control c in controls)
        {
            if (c is UserControl)
                BuildUp(c);

            BuildUpControls(c.Controls);
        }
    }

    private void BuildUpMaster(MasterPage page)
    {
        if (page != null)
        {
            BuildUp(page);
            BuildUpMaster(page.Master);
        }
    }

}

My pages and controls all inherit off base implementations which handle the dependency injection e.g.

public class MyBaseUserControl : UserControl
{
    [Dependency]
    public IMyServiceProvider MyService { get; set; }
}

public class MyPage : Page
{
    [Dependency]
    public IMyServiceProvider MyService { get; set; }
}

My Dependency Injection is working as planned, however when I use GridViews on my pages the OnRowEditing etc commands dont fire for the GridView. Its as if the events arent hooked up. I have set the events in the HTML as follows.

<asp:GridView ID="gvComplaintCategory" runat="server" AutoGenerateColumns="False" DataKeyNames="ComplaintCategoryID" BackColor="#FFFFFF" GridLines="None" 
        CellPadding="2" CellSpacing="2" AllowPaging="True" PageSize="8" ShowFooter="true" 
        OnRowCommand="gvComplaintCategory_OnRowCommand" 
        OnRowEditing="gvComplaintCategory_OnRowEditing" 
        OnRowCancelingEdit="gvComplaintCategory_OnRowCancelingEdit">

                <asp:TemplateField>
                    <HeaderTemplate>Complaint Category Name</HeaderTemplate>
                    <EditItemTemplate>
                       <asp:TextBox ID="txtComplaintCategoryEdit" runat="server" CssClass="textbox" Text='<%# DataBinder.Eval(Container.DataItem, "ComplaintCategoryName") %>'></asp:TextBox>
                        &nbsp;
                        <asp:RequiredFieldValidator ID="rfvComplaintCategoryEdit" runat="server" ControlToValidate="txtComplaintCategory" Text="*" CssClass="RequiredFieldValidator" ValidationGroup="dgComplaintCategory"></asp:RequiredFieldValidator>
                    </EditItemTemplate>
                    <ItemTemplate>
                        <asp:Label ID="lblComplaintCategory" runat="server" CssClass="label" Text='<%# DataBinder.Eval(Container.DataItem, "ComplaintCategoryName") %>'></asp:Label>
                    </ItemTemplate>
                    <FooterTemplate>
                       <asp:TextBox ID="txtComplaintCategoryNew" runat="server" CssClass="textbox"></asp:TextBox>
                        &nbsp;
                        <asp:RequiredFieldValidator ID="rfvComplaintCategoryNew" runat="server" ControlToValidate="txtComplaintCategoryNew" Text="*" CssClass="RequiredFieldValidator" ValidationGroup="dgComplaintCategory"></asp:RequiredFieldValidator>
                    </FooterTemplate>
                </asp:TemplateField>
                <asp:TemplateField>
                    <EditItemTemplate>
                        <asp:Button ID="btnComplaintCategoryUpdate" runat="server" CssClass="button" CommandName="Update" Text="Update" CausesValidation="true" ValidationGroup="dgComplaintCategory"/>
                        &nbsp;
                        <asp:Button ID="btnComplaintCategoryDelete" runat="server" CssClass="button" CommandName="Delete" Text="Delete" CausesValidation="false" ValidationGroup="dgComplaintCategory"/>
                        &nbsp;
                        <asp:Button ID="btnComplaintCategoryCancel" runat="server" CssClass="button" CommandName="Cancel" Text="Cancel" CausesValidation="false" ValidationGroup="dgComplaintCategory"/>
                    </EditItemTemplate>
                    <ItemTemplate>
                        <asp:Button ID="btnComplaintCategoryEdit" runat="server" CssClass="button" CommandName="Edit" Text="Edit" CausesValidation="false" ValidationGroup="dgComplaintCategory"/>
                    </ItemTemplate>
                    <FooterTemplate>
                        <asp:Button ID="btnComplaintCategoryAdd" runat="server" CssClass="button" CommandName="Add" Text="Add" CausesValidation="true" ValidationGroup="dgComplaintCategory"/>
                    </FooterTemplate>
                </asp:TemplateField>  
            </Columns>  
    </asp:GridView>

I also have autoeventwireup set to true on the pages and master page. Can anyone shed any light on why the events are not firing? Is my Unity http module causing this to happen by dropping the event wiring? I can get this to work no problem in a basic example with no IoC involved.

Any help would be greatly appreciated.

Thanks

Matt


回答1:


The reason is that you are modifying the controls before they load their ViewState.

Moving build-up on PreLoad should work, because ViewState is loaded before the PreLoad event

private void OnPreRequestHandlerExecute(object sender, EventArgs e)
{
    IHttpHandler currentHandler = HttpContext.Current.Handler;
    HttpContext.Current.Application.GetContainer().BuildUp(
                        currentHandler.GetType(), currentHandler);

    // User Controls are ready to be built up after page initialization is complete
    var currentPage = HttpContext.Current.Handler as Page;
    if (currentPage != null)
    {
        currentPage.PreInit += Page_PreInit;
        currentPage.PreLoad += Page_PreLoad;
    }
}

// Build up each control in the page's control tree
private void Page_PreInit(object sender, EventArgs e)
{
    var currentPage = (Page)sender;

    BuildUp(currentPage);

    BuildUpMaster(currentPage.Master);
}

private void Page_PreLoad(object sender, EventArgs e)
{
    var currentPage = (Page)sender;

    BuildUpControls(currentPage.Controls);
}


来源:https://stackoverflow.com/questions/4852396/asp-net-4-0-gridview-onrowediting-events-not-firing-when-using-unity-2-0-http-mo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!