使用母版页属性作为属性扩展ASP.NET页

使用母版页属性作为属性扩展ASP.NET页,asp.net,master-pages,Asp.net,Master Pages,我有一个基于身份验证角色的系统:不同的角色被重定向到不同的文件夹,每个文件夹中都有一个web.config,只允许访问特定的用户名 很少有角色具有与gridview相同的默认页面,gridview根据角色以不同的方式作出反应(显示不同的列,事件触发不同的方法,等等) 所以我的问题是,每次我需要对一个页面进行微小更改时,我都需要将相同的更改复制/粘贴到其他文件夹中的所有其他默认页面 在代码方面,我通过创建一个DefaultFather类来解决这个问题,该类扩展System.Web.UI.Page,

我有一个基于身份验证角色的系统:不同的角色被重定向到不同的文件夹,每个文件夹中都有一个web.config,只允许访问特定的用户名

很少有角色具有与gridview相同的默认页面,gridview根据角色以不同的方式作出反应(显示不同的列,事件触发不同的方法,等等)

所以我的问题是,每次我需要对一个页面进行微小更改时,我都需要将相同的更改复制/粘贴到其他文件夹中的所有其他默认页面

在代码方面,我通过创建一个DefaultFather类来解决这个问题,该类扩展System.Web.UI.Page,其他所有默认类都继承自DefaultFather。这样,如果我不声明页面寿命方法,将触发DefaultFather方法

但是图形部分(html、javascript、asp组件等)呢

我只为默认页面创建了NestedMasterPage,但每次需要更改控件(gridview、按钮、链接按钮)的外观/行为时,我都必须使用FindControl()方法

真的没有别的办法解决这个问题吗? 我想用Page_Load()方法用FindControl()搜索每个控件,并将它们保存到属性中供以后使用,但这看起来并不是一个好的解决方案。 如果我可以使用母版页组件作为属性,那就太好了,但我认为为了做到这一点,我应该创建公共属性,我不知道这是否会导致某种安全问题

有什么建议吗


顺便说一句,如果母版页是解决方案,我应该删除DefaultFather类并将代码直接放入母版页吗?或者仅仅为代码使用另一个类是一个好主意吗?

我认为为页面同时使用母版页和基类没有什么错。它们有不同的用途。母版页通常都是关于布局的,基类是关于页面功能的

如果您想操作母版页上的标记,而不是直接访问字段,我会说创建一个逻辑函数来完成您需要它做的事情,并让母版页来完成

// Site.Master.cs
public void HideSubmitButton()
{
    btnSubmit.Visible = false;
}

// Default.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
    ((SiteMaster)Master).HideSubmitButton();
}
我可能会包装该cast,以便您可以更轻松地使用它-这是属于基类的内容:

// DefaultFather.cs
protected new SiteMaster Master { get { return (SiteMaster)base.Master; } }

// Default.aspx.cs
Master.HideSubmitButton();
编辑

根据您关于附加事件处理程序的评论-如果您需要将事件附加到主服务器上的对象(这可能不是一个好主意-理想情况下,主服务器上的事件处理程序位于主服务器上-但如果您确实需要它),您也可以公开方法来执行此操作,如:

// Site.Master.cs
public void AttachEventHandlerToGoButton(EventHandler eventHandler)
{
    btnGo.Click += eventHandler;
}

// Default.aspx.cs
Master.AttachEventHandlerToGoButton(DoMyThing);

private void DoMyThing(object sender, EventArgs e) { }
或者,如果您想获得更多乐趣,请编写一个包装器事件:

// Site.Master
<asp:Button ID="btnGo" runat="server" OnClick="btnGo_Click" />

// Site.Master.cs
public event EventHandler GoButtonClick;

protected void btnGo_Click(object sender, EventArgs e) {
    if (GoButtonClick != null) {
        GoButtonClick(sender, e);
    }
}

// Default.aspx.cs
Master.GoButtonClick += DoMyThing;

private void DoMyThing(object sender, EventArgs e) { }
//Site.Master
//Site.Master.cs
公共事件事件处理程序GoButtonClick;
受保护的无效btnGo\u单击(对象发送者,事件参数e){
if(GoButtonClick!=null){
GoButtonClick(发送方,e);
}
}
//Default.aspx.cs
Master.GoButtonClick+=DoMyThing;
私有无效域(对象发送方,事件参数e){}

还可以在主包装器上查看我的编辑-您需要
基。
在那里避免堆栈溢出。

有趣的是,事件如何?如何响应示例中的OnClick事件?我不能声明:private SiteMaster;并在默认类中的页面_Init()上对其进行序列化?对我来说,这似乎比使用可能导致问题的新工具更容易。最后一件事,如果可以的话。。。所以现在我有一个主文件和一个基本的DefaultFather类,以及其他扩展DefaultFather的默认类。如果我问一个关于如何处理一个OnClick()事件的例子,这个事件应该根据不同的default.aspx执行不同的操作,这是不是太过分了?当然,
Master
包装器的单独字段或属性可以正常工作,这只是一个首选项。但是不要害怕使用
new
——这有点不常见,但只要使用得当,它确实可以正常工作。对于
OnClick
这件事,我下面的两个示例演示了如何做到这一点。您的按钮位于母版页中,但母版页在单击时不会执行任何操作,而只是公开了一种将事件附加到母版页的方法。您的页面可以附加它想要的任何事件处理程序-在我的示例中,
DoMyThing
方法(位于页面代码隐藏中)会附加到母版页的btnGo,即使页面对按钮本身一无所知。每个页面都可以在这里附加它想要的任何处理程序。谢谢伙计!我听从了你的建议,现在一切都很漂亮,工作也很完美:)