Obsidian Obsidian - 7 months ago 8
Vb.net Question

How to access a top level master page sub from within a nested page?

MASTER PAGE STRUCTURE

TOP MASTER
PAGE MASTER "TopMaster.ErrorMsg(ErrMsg) Here throws NO error"
PAGE "TopMaster.ErrorMsg(ErrMsg) Here throws error"


I am unable to gain access to the top level class from the base page.

TOP MASTER ASPX

<asp:Literal ID="litMsg" runat="Server"/>


PAGE.VB

Partial Public Class BasePage
Inherits System.Web.UI.Page

Public Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
TopMaster.ErrorMsg(ErrMsg)
"Error BC30451: TopMaster is not declared it may be inaccessible due to its protection level."
End Sub

End Class


MASTER.VB

Partial Public Class PageMaster
Inherits System.Web.UI.MasterPage

End Class


TOP MASTER.VB

Partial Public Class TopMaster
Inherits System.Web.UI.MasterPage

Public Shared Sub ErrorMsg(ErrMsg As String)
Dim myPage = TryCast(HttpContext.Current.Handler, Page)

If myPage IsNot Nothing Then
Dim master = myPage.Master
Dim myMaster = TryCast(master.Master, TopMaster)
While master.Master IsNot Nothing AndAlso myMaster Is Nothing
master = master.Master
myMaster = TryCast(master, TopMaster)
End While

myMaster.litMsg.Text = ErrMsg
End If

End Sub

End Class

Answer

Update: now it's clear, make the class Public, otherwise you can't access it:

Partial Public Class TopMaster

You should show us the exact error message including stacktrace. It seems that the type Top Master is not declared which makes no sense since you are in the class TopMaster.

So i doubt that following fixes your core issue "Error: Top Master is not declared" but it might be useful anyway.

If you want to access that literal you should provide a property in your TopMaster like this:

Public Property ErrorMsg As String
    Get
        Return Me.litMsg.Text
    End Get
    Set(value As String)
        Me.litMsg.Text = value
    End Set
End Property

On this way you can even change the control-type if you want without breaking the code. Its much better than to expose the control itself.

I guess you also have to move the assignment from inside the loop to outside. You should also use Dim myMaster = TryCast(master, TopMaster) at the beginning instead of jumping directly to the page's master's master as you do with TryCast(master.Master, TopMaster):

Public Shared Sub ErrorMsg(ErrMsg As String)
    Dim myPage = TryCast(HttpContext.Current.Handler, Page)

    If myPage IsNot Nothing Then
        Dim master = myPage.Master
        Dim myMaster = TryCast(master, TopMaster)
        While master.Master IsNot Nothing AndAlso myMaster Is Nothing
            master = master.Master
            myMaster = TryCast(master, TopMaster)
        End While
        myMaster.ErrorMsg = ErrMsg
    End If

End Sub

Otherwise you are only assigning the ErrorMsg if the master is the page's master's master's master or it's even more deeply nested.

Comments