0

My content pages allow me to manipulate data and so, their code includes error handling blocks. What I'd like to do is set the text value for several labels in a modal window on the master page in order to display the error message to the user:

<!-- master page -->
<div runat="server" id="divModalBg" class="modalbg"> </div>
<div runat="server" id="divErrorModal" class="modal">
    <asp:Label runat="server" id="lblErrorTitle"></asp:Label>
    <asp:Label runat="server" id="lblErrorMessage"></asp:Label>
    <asp:Button runat="server" id="btnRetry" text="Retry" />
</div>

I'm not sure how I would set the values for those labels in my content page...

// Users.aspx.cs
protected void btnUpdate_Click(object sender, EventArgs e)
{
    try
    {
        // do some stuff
    }
    catch(Exception ex)
    {
        // lblErrorTitle = "Update User";
        // lblErrorMessage = String.Format("Error actioning request: [ {0} ]", ex.Message);
        // btnRetry just closes the modal (sets visible to false) so that
        // the user can try again
    }
}

So how can I access the controls on the master page so that I can do this?

I'm thinking properties on the master page, set them onPageLoad...

EDIT
As per mason's answer below, I've done this...

// Default.master
// properties for error handling
public virtual Label ErrorTitle { get { return lblErrorAction; } }
public virtual Label ErrorMessage { get { return lblErrorMessage; } }
public virtual Panel ErrorBG { get { return pnlErrorBackground; } }
public virtual Panel ErrorModal { get { return pnlErrorModal; } }

Here's my directive:

<%@ MasterType VirtualPath="~/Default.master" %>

And here's my code file

// Users.aspx.cs
private void deleteUser(int userid)
{
    ImajUser u = new ImajUser(userid, true);
    try
    {
        u.Delete();

        lblerr.Text = "User was deleted successfully.";
        lblerr.ForeColor = System.Drawing.Color.Green;
    }
    catch (Exception ex)
    {
        Page.Master.ErrorTitle.Text = "Delete User";
        Page.Master.ErrorMessage.Text = String.Format("Error actioning request: [ {0} ]", ex.Message);
        Page.Master.ErrorBG.Visible = true;
        Page.Master.ErrorModal.Visible = true;

    }

Now getting the following error for each of these controls:

'System.Web.UI.MasterPage' does not contain a definition for 'ErrorTitle' and no extension method 'ErrorTitle' accepting a first argument of type 'System.Web.UI.MasterPage' could be found (are you missing a using directive or an assembly reference?)

Ortund
  • 8,095
  • 18
  • 71
  • 139

2 Answers2

2

Although Thor's answer would work, there's a much better way. Set the master type on the content page by putting this in the ASPX file. Obviously, replace the TypeName with the name of the class from your master page's code behind.

<%@ MasterType TypeName="MyMasterClassName" %>

This makes your master page strongly typed accessible from the content page. Then, to access controls on the MasterPage (which are by default private or protected, not sure which) you'll need to use properties to expose them as public. So put this on your master page code behind...

public virtual Label LblErrorMessage { get {return lblErrorMessage;}}

Then from your code behind, you can access it like this...

Master.LblErrorMessage.Text="Hello, world!";
mason
  • 31,774
  • 10
  • 77
  • 121
  • By the way, if you want to implement client side error notifications, there's a much nicer way of doing it. Use a client side notification library, my favorite being [Noty](http://ned.im/noty/). I used to use plain labels and timers like it appears you'll be attempting, but having a client side script handle it proved a much more elegant solution. – mason May 09 '14 at 12:42
  • it doesn't seem to be working... `'System.Web.UI.MasterPage' does not contain a definition for 'ErrorTitle' and no extension method 'ErrorTitle' accepting a first argument of type 'System.Web.UI.MasterPage' could be found (are you missing a using directive or an assembly reference?)` – Ortund May 09 '14 at 13:12
  • @Ortund I've updated my answer, I modified the MasterType directive slightly if you'll take a look at it. – mason May 09 '14 at 14:26
  • Okay so my master page is `public partial class _Default : System.Web.UI.MasterPage` so then TypeName would be `_Default`? – Ortund May 09 '14 at 14:29
  • @Ortund Yes, that is correct. But I might suggest you rename it to something like `DefaultMasterPage` so that it's less confusing. – mason May 09 '14 at 15:00
  • I didn't rename it, but I'm getting first chance exceptions after the code in my catch block executes. Also, the debugger closes down at the same time, as does my web browser – Ortund May 09 '14 at 17:07
  • Sounds like you have a separate issue then. I'd make a new question and describe your new issue. Make sure you provide the relevant code and the exception and let us know which line the exception happens on. – mason May 09 '14 at 17:10
0

You can access any public methods in your master page using this kind of contruct:

In page.aspx:

if (Page.Master != null)
                     ((YourMasterPageType)Page.Master).SetError("your error txt");

In your master page:

public void SetError(string errMsg)
        {
            ErrCtrl.Visible = true;
            ErrCtrl.Text(errMsg);
        }
Thor
  • 291
  • 2
  • 8
  • wasn't able to access the properties, but I did do this... `Label lblErrorTitle = (Label)Page.Master.FindControl("lblErrorTitle"); lblErrorTitle.Text = "Update User";` ... and so on – Ortund May 09 '14 at 12:35
  • I suggest you make a public method in your master page code behind like the example SetError. This way if your masterpage controls change, you do not have to alter each individual page. And you have to cast Page.Master to you master page type. Let's say your master page is called 'Site.Master' then you call the function like this: ((Site)Page.Master).SetError("your error txt"); – Thor May 09 '14 at 12:46