How to correctly build a messaging system.

95 pts.
Tags:
ASP
ASP.NET
User controls
Hi. I am trying to build a messaging system for a website for my company. The problem is that the system needs to be able to post up user messages any time, with an easy script like AddNewMessage("something happened",MessaveSeverity.Error); The system I have works fine - as long as the page has been loaded first. However, some of our developers noticed that if you try to add a message during your own Page_load call, it does not show up. (For example, an information message explaining why some DropDownLists are empty) Here is the code I have so far. I have worked very,very hard trying to get this to work, and I just cannot seem to find the solution. Please, please - any help on this would be amazing. I am going on two days of googling here and I have a fair knowledge of this stuff, having made a few controls already. Even if it's just a suggestion please let me know :) crab Note: the only thing on the master page of note is a Panel with ID new_message_ Note: I call this from a ASPX page by saying
m = (BMW_Master)Master;
m.AddNewMessage("first error", MessageSeverity.Information);
This works fine, unless we are inside the ASPX's Page_Load call, in which case the control is added, but does not render Note: important section is in bold
    public enum MessageSeverity
    {
        Error, Information, Success
    }

    public partial class BMW_Master : System.Web.UI.MasterPage
    {
        private void Page_Load(object sender, System.EventArgs e)
        {
            reCreateMessages();

            if (IsPostBack)
                return;

            // If we are on a new page, clear any old
            // messages
            ClearAllMessages();
        }
        private void reCreateMessages()
        {
            if (ViewState["messages"> == null ||
                ViewState["messages">.ToString() == "" ||
                ViewState["messages">.ToString() == String.Empty)
                return;

            // Create the regex
            string messages = (string)ViewState["messages">;
            Regex reg = new Regex(@"~(?<message>.+?)*(?<severity>.+?);");
            Match m = reg.Match(messages);

            // extract the variables
            while (m.Success)
            {
                string message = m.Groups["message">.ToString(),
                      severity = m.Groups["severity">.ToString();

                MessageSeverity _severity = MessageSeverity.Error;

                if (severity == "Information")
                    _severity = MessageSeverity.Information;
                else if (severity == "Error")
                    _severity = MessageSeverity.Error;
                else if (severity == "Success")
                    _severity = MessageSeverity.Success;

                new_message_.Controls.Add(new BMW_Message(message, _severity));
                
                m = m.NextMatch();
            }
 
        }

        public void ClearAllMessages()
        {
            new_message_.Controls.Clear();
        }

        public void AddNewMessage(string _message)
        {
            AddNewMessage (_message,MessageSeverity.Error);
        }

        public void AddNewMessage(string _message, MessageSeverity _severity)
        {
            // Remove used special characters
            _message = _message.Replace("~", "~");
            _message = _message.Replace("*", "*");
            _message = _message.Replace(";", ";");

            BMW_Message m = new BMW_Message(_message, _severity);
            new_message_.Controls.Add(m);

            if (!IsPostBack)
                    // Do something special to cause the control to work correctly
                       
            ViewState["messages"> += "~" + _message + "*" + _severity.ToString() + ";";
        }


        public void Clear_All_Click(object sender, EventArgs e)
        {
            ViewState["messages"> = null;
            new_message_.Controls.Clear();
        }

        public void Clear_Me_Click(object sender, EventArgs e)
        {
            Button b = (Button)sender;
            BMW_Message message = (BMW_Message)b.Parent;
            string vs_string = message.ViewStateString;

            string vs = ViewState["messages">.ToString();
            vs = vs.Replace(vs_string, "");

            ViewState["messages"> = vs;
            if (vs == "")
                ViewState["messages"> = null;

            new_message_.Controls.Remove(message);
        }
    }
}


public class BMW_Message : CompositeControl
{
    private string _message;
    private CUTS.MessageSeverity _severity;

    public BMW_Message(string message, CUTS.MessageSeverity severity)
    {
        this._message = message;
        this._severity = severity;
    }

    public string ViewStateString
    {
        get
        {
            return "~" +
                   _message + "*" +
                   _severity.ToString() + ";";
        }
    }

    protected override void CreateChildControls()
    {
        Controls.Clear();
        CreateControlHierarchy();
        ClearChildViewState();
    }

    public void ForceRender()
    {
        //CreateChildControls();
        //StringBuilder result = new StringBuilder(1024);
        //.RenderControl(new HtmlTextWriter(new StringWriter(result)));
       // return result.ToString();
        this.RecreateChildControls();
    }

    protected virtual void CreateControlHierarchy()
    {
        string div_style = String.Empty;
        Color button_BackColors = Color.Transparent;

        if (_severity == CUTS.MessageSeverity.Information)
        {
            div_style = "border: solid 3px gold; background-color: yellow; padding-left: 10px;";
            button_BackColors = Color.Yellow;
        }
        else if (_severity == CUTS.MessageSeverity.Success)
        {
            div_style = "border: solid 3px dark green; background-color: green; padding-left: 10px;";
            button_BackColors = Color.Green;
        }
        else // Default to Error
        {
            div_style = "border: solid 3px dark red; background-color: red; padding-left: 10px;";
            button_BackColors = Color.Red;
        }

        // Panel Containing this, Then Form, Then to the BMW_Master
        CUTS.BMW_Master m = (CUTS.BMW_Master)Parent.Parent.Parent;

        LiteralControl div_start = new LiteralControl("<div style='" + div_style + "'>");

        Button Clear_Me = new Button();
        Clear_Me.Text = " X ";
        Clear_Me.BackColor = button_BackColors;
        Clear_Me.Style.Add("float", "left");
        Clear_Me.Style.Add("position", "relative");
        Clear_Me.Style.Add("left", "-19px");
        Clear_Me.Style.Add("top", "-10px");
        Clear_Me.Click += new EventHandler(m.Clear_Me_Click);

        Button Clear_All = new Button();
        Clear_All.Text = "Clear All";
        Clear_All.BackColor = button_BackColors;
        Clear_All.Style.Add("position", "relative");
        Clear_All.Style.Add("left", "-19px");
        Clear_All.Style.Add("top", "-10px");
        Clear_All.Click += new EventHandler(m.Clear_All_Click);



        Label Message = new Label();
        Message.Text = _message;

        LiteralControl div_end = new LiteralControl("</div>");

        this.Controls.Add(div_start);
        this.Controls.Add(Clear_Me);
        this.Controls.Add(Clear_All);
        this.Controls.Add(Message);
        this.Controls.Add(div_end);
    }
}

Answer Wiki

Thanks. We'll let you know when a new response is added.

The answer we eventually implemented was very similar to what is shown here. In a nutshell, we used one div on the master page that had label controls added dynamically once each message was generated. Based on the type of message, the label would get a different CSS class, so the overall look was one messge center where different color messages could come out.

We added a clear messages text link to the div, which would simply cause some javascript to make the div invisible.

If the user posted back to the page, the div automatically disappeared (as we did not preserve the data, and we automatically set the div visible to false on every postback.).

If a sub page requested a message to be shown, we made the div was visible and added the label.

Hope that helps someone,
crabpot

Discuss This Question:  

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when members answer or reply to this question.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

To follow this tag...

There was an error processing your information. Please try again later.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy

Thanks! We'll email you when relevant content is added and updated.

Following