Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Accessing a Master Page from Another PROJECT 1

Status
Not open for further replies.

robertfah

Programmer
Mar 20, 2006
380
US
Similar to one of my previous posts, I have a website that houses many other projects, mainly layers (data access, configuration, etc.). I have a Base Class project that all my web pages inherit from (ASIBasePage) and I'd like to access controls on the Master Page and change them from this BasePage class. I can do this from the inherited page (index.aspx) like so:

((scMaster)this.Master).TitleName = " Welcome " + SiteData.UserInformation.Instance.Title + " " + SiteData.UserInformation.Instance.FirstName + " " +
SiteData.UserInformation.Instance.LastName;
((scMaster)this.Master).LogoURL = "~/images/logos/" + SiteData.Customer.Instance.CustomerCode + "_logo.jpg";

But I have since moved this code to my ASIBasePage project in the overrideable method OnLoad. Now I know it's not going to work because it can't locate the scMaster page, but does anyone know how I can accomplish this?
 
Is this a real difficult thing to do? I can't imagine so, but no one has replied to my first post. Anyone have ANY ideas?
 
A MasterPage is a UserControl, and you can't easily share them across projects (they're not made for that level of reuse). The easiest thing to do would be to deploy the given MasterPage to each website.

One thing you CAN do, however, is compile the MasterPage code-behind into an assembly (after downloading the Web Deployment Projects add-in) and have your local MasterPage inherit from the deployed MasterPage. This is advantageous because it lets you tweak the appearance per application while effectively sharing the functionality.
 
BoulderBum,
Thanks for the advice, but I think you're thinking I'm trying to do something different. I've got a website that uses a single MasterPage for all it's pages; index.aspx, main.aspx, etc. they all use this MasterPage. Those same pages (except Master) inherit from a Base Page Class called ASIBasePage. In this Base Page class I do some small configuration that each page requires and that's it. One of the things I would like to accomplish is this: On my MasterPage, there are 3 label controls that need to change with every page. I could put the same exact code on every OnLoad event of each page, that would extend to over 80 pages, making changes not so efficient. So I'd like to access those 3 labels from my Base Page Class and change them from within there. That way my code is the same for all pages and in one place.

The issue becomes that the Base Page Class is a seperate project that is added to the website, so it's in an entirely different namespace, etc. So I can't see the MasterPage of my website within this Base Page Class.

Does anyone know how I can do this? A friend mentioned Interfaces, but I'm not too familiar with those.
 
Oh, then it's not too hard.

The easiest way is to expose the text of the three labels as public properties of the base page, then cast the Page property of the MasterPage to your base Page type and read the properties.

Code:
CustomPage basepage = Page as CustomPage;
string whatever = basepage.SomeProperty;

Alternately, you can define multiple ContentPlaceHolders for the MasterPage and set the content via the designers in each of the Pages.
 
Ok, That's the big problem.....where your code is this:

CustomPage basepage = Page as CustomPage

I'm assuming you are using CustomPage as my MasterPage right? If so, my MasterPage is called scMaster. I can't see the class scMaster from my Base Page Class.

Maybe I'm missing something or doing something wrong....
 
Maybe this will help more... This is my Master Page called scMaster:

public string TitleName
{
get
{
this.EnsureChildControls();
return lblTitleName.Text;
}
set
{
this.EnsureChildControls();
lblTitleName.Text = value;
}
}

public string SiteName
{
get
{
this.EnsureChildControls();
return lblSiteName.Text;
}
set
{
this.EnsureChildControls();
lblSiteName.Text = value;
}
}

There is more, but for brevity, I used only 2. As you can see, I have them setup as properties already, so I can access them from another page, like my index page.

So in my index.aspx page I COULD do this:
This line is just to show that I inherit from my Base Page Class
public partial class main : ASIBasePage

Code in OnLoad event:
((scMaster)this.Master).TitleName = " Welcome " + session["UserName"].ToString();

((scMaster)this.Master).SiteName = session["SiteName"].ToString();


And that works fine. But I'd have to do that on EVERY page, UGH! So I'd like to put it in my Base Page Class called ASIBasePage which is a seperate project added to my website:

public class ASIBasePage : System.Web.UI.Page
{
protected override void OnLoad(EventArgs e)
{
//This is where I'd like the above code to reside, BUT I can't get the reference to scMaster.
}
}

Does this make more sense?
 
Try referencing the BasePage from your MasterPage, not the other way around. The dynamic compilation model of ASP.NET makes what you're trying to do there difficult.

Also, instead of having the label with the user name, you should probably consider the built-in LoginName control and instead of setting the site name, you may want to tap into the Membership.ApplicationName if it will work.

One more thing of mentions is that you can potentially abstract the properties you're setting into their own class, the reference that class from both the Page and MasterPage.

What you can consider is setting up is a Session-based singleton (to store all your information, make it easily accessible through properties and only take up one name in the Session variables to make it happen):

Code:
public class InformationManager
{
    private InformationManager(){ site = null; }
    
    private string site;
    public string SiteName
    {
        get{ return site; }
        set{ site = value; }
    }

    public static InformationManager SessionInstance
    {
        get
        {
           InformationManager manager = Sesssion["InfoManager"];
           
           //NOTE: not thread-safe, though it probably
           //      won't need to be
           if( manager == null )
           {
                manager = new InformationManager();
                Session["InfoManager"] = manager;
           }

           return manager;
        }
    }
}

That way, from your MasterPage you can access the properties like:

Code:
string s = InformationManager.SessionInstance.SiteName;

...and you can set the site name, say from the page, like:

Code:
InformationManager.SessionInstance.SiteName = "whatever";

You can do some things to spice up the functionality (adding changed events and subscribing to them in the MasterPage for example), but you get the basic idea.
 
Yeah, I basically did that but excused it from the code because I didn't want to confuse anyone. I created a class that I use to store all my information about the user in. It's a class called SiteData and it's a sealed class that holds data throughout the lifetime of a web session. So my labels are only holding data about a user after they login....but our site gives the ability for a user to SWITCH USERS and login as someone else on the fly and see their information. It's a confusing situation, but those 3 labels:

//((scMaster)this.Master).TitleName = " Welcome " + SiteData.UserInformation.Instance.Title + " " +
// SiteData.UserInformation.Instance.FirstName + " " +
// SiteData.UserInformation.Instance.LastName;
//((scMaster)this.Master).LogoURL = "~/images/logos/" + SiteData.Customer.Instance.CustomerCode + "_logo.jpg";
//((scMaster)this.Master).SiteName = SiteData.UserInformation.Instance.SiteName;
//((scMaster)this.Master).Logout = "If you are not " + SiteData.UserInformation.Instance.Title + " " +
// SiteData.UserInformation.Instance.FirstName + " " +
// SiteData.UserInformation.Instance.LastName + ", please <a href='logout.aspx' class='style5'>logout</a>";

Could potentially change on every page, not the static data, just the SiteData.UserInformation data. So instead of having to put the above code on all 80 somewhat pages in the Page_Load event, I was thinking of putting it in the BasePage class so it's localized and in 1 place incase it ever has to change.
 
excuse the wacks (//), they;re supposed to be uncommented.
 
Ok, so I've done some research and have thought about the previous posts and found that if I put the above code in my Page_Load event of the MasterPage, then it works fine. Not quite sure why I didn't try or think of this before, but I guess that's what happens when you work alone.

Thanks for all the ideas/comments. I always learn something from these posts!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top