【问题标题】:extending ASP.NET Page using MasterPage attributes as properties使用 MasterPage 特性作为属性扩展 ASP.NET 页面
【发布时间】:2013-04-10 20:21:20
【问题描述】:

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

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

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

就代码而言,我通过创建一个扩展 System.Web.UI.Page 的 DefaultFather 类解决了问题,并且所有其他 Default 类都继承自 DefaultFather。这样,如果我不声明Page-life-method,就会触发DefaultFather方法。

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

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

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

有什么建议吗?

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

【问题讨论】:

    标签: asp.net master-pages


    【解决方案1】:

    我会说为您的页面同时拥有母版页和基类并没有错。它们服务于不同的目的。母版页通常都是关于布局的,而基类是关于页面功能的。

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

    // Site.Master.cs
    public void HideSubmitButton()
    {
        btnSubmit.Visible = false;
    }
    
    // Default.aspx.cs
    protected void Page_Load(object sender, EventArgs e)
    {
        ((SiteMaster)Master).HideSubmitButton();
    }
    

    我可能会包装该演员表,以便您可以更轻松地使用它 - 这是属于您的基类的东西:

    // 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) { }
    

    另请参阅我对 Master 包装器的编辑 - 您需要在那里使用 base. 以避免堆栈溢出。

    【讨论】:

    • 有趣,事件呢?如何响应示例的 OnClick 事件?
    • 我不能只声明:私有 SiteMaster 主;并在默认类的 Page_Init() 上初始化它?对我来说,这似乎比使用可能会导致问题的 new 更容易。如果可以的话,还有最后一件事......所以现在我有一个主文件和一个基本的 DefaultFather 类,以及其他扩展 DefaultFather 的 Default 类。如果我问一个关于如何处理 OnClick() 事件的示例,该事件应该根据不同的 default.aspx 采取不同的行动,这是否太过分了?
    • 当然,Master 包装器的单独字段或属性可以正常工作,这只是一个偏好。但是不要害怕使用new - 这有点不常见,但只要你正确使用它就可以正常工作。
    • 对于OnClick 的事情,我下面的两个例子展示了如何做到这一点。您的按钮位于母版页中,但母版页在单击时不执行任何操作,而只是公开了一种将事件附加到它的方法。您的页面可以附加它想要的任何事件处理程序 - 在我的示例中,位于页面代码隐藏中的 DoMyThing 方法被附加到母版页的 btnGo,即使该页面对按钮本身一无所知。每个页面都可以在这里附加它想要的任何处理程序。
    • 谢谢老兄!我听从了你的建议,现在一切都很漂亮而且工作得很好:)
    猜你喜欢
    • 1970-01-01
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-25
    相关资源
    最近更新 更多