События ASP.NET 4.0 GridView OnRowEditing не запускаются при использовании http-модуля Unity 2.0 - PullRequest
3 голосов
/ 31 января 2011

У меня есть сайт веб-форм ASP.NET с использованием мастер-страниц.Он использует Unity в качестве моего контейнера IoC.Я создал модуль HTTP для создания контейнера, используя несколько учебных пособий, которые я нашел в Интернете.Мне нужно, чтобы внедрение зависимостей работало для пользовательских элементов управления, и единственный способ, которым я смог заставить это работать, состоял в том, чтобы подключиться к событию Pages PreInit, как видно из кода ниже.

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

}

Мои страницыи контролирует все наследования от базовых реализаций, которые обрабатывают внедрение зависимостей, например

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

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

Мое внедрение зависимостей работает как запланировано, однако, когда я использую GridViews на своих страницах, команды OnRowEditing и т. д. не запускаются для GridView.Как будто события не подключены.Я установил события в HTML следующим образом.

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

У меня также установлено значение true для autoeventwireup на страницах и главной странице.Кто-нибудь может пролить свет на то, почему события не стреляют?Мой модуль Unity http вызывает это, сбрасывая проводку события?Я могу заставить это работать без проблем в базовом примере без участия IoC.

Любая помощь будет принята с благодарностью.

Спасибо

Matt

1 Ответ

2 голосов
/ 16 февраля 2011

Причина в том, что вы изменяете элементы управления до того, как они загрузят свой ViewState.

Перемещение сборки в PreLoad должно работать, потому что ViewState загружается до события PreLoad

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