我有一个使用母版页的 ASP.NET Web 表单网站。它使用 Unity 作为我的 IoC 容器。我创建了一个 HTTP 模块来使用我在网上找到的几个教程来构建容器。我需要依赖注入(inject)才能为用户控件工作,而我能够使其工作的唯一方法是 Hook 到 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);
}
}
}
我的页面和控件都继承了处理依赖项注入(inject)的基本实现,例如
public class MyBaseUserControl : UserControl
{
[Dependency]
public IMyServiceProvider MyService { get; set; }
}
public class MyPage : Page
{
[Dependency]
public IMyServiceProvider MyService { get; set; }
}
我的依赖注入(inject)正在按计划工作,但是当我在页面上使用 GridView 时,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>
<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>
<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"/>
<asp:Button ID="btnComplaintCategoryDelete" runat="server" CssClass="button" CommandName="Delete" Text="Delete" CausesValidation="false" ValidationGroup="dgComplaintCategory"/>
<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>
我还在页面和母版页上将 autoeventwireup 设置为 true。任何人都可以解释为什么事件没有触发吗?我的 Unity http 模块是否通过删除事件接线导致发生这种情况?我可以在不涉及 IoC 的基本示例中让它正常工作。
任何帮助将不胜感激。
谢谢
马特
最佳答案
原因是您在控件加载其 ViewState 之前修改了控件。
在 PreLoad 上移动构建应该可以,因为 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);
}
关于使用 Unity 2.0 http 模块时,ASP.NET 4.0 GridView OnRowEditing 事件不会触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4852396/