Today, something completely relaxing and simple. The whole thing comes down to inserting a single HTML tag into the aspx file:
<p class="chyba" id="errors" runat="server" visible="false" enableviewstate="false">
<p></p>which will not appear in the resulting markup at all thanks to Visible="false", and will not be shown again even if the user refreshes (reloads) the page (EnableViewState="false").
Next, I create a SunamoPage class, from which I derive the site’s Page class (for example GgdagPage), and from GgdagPage I derive every aspx page in the web application. In the SunamoPage class I have created these variables and events:
protected HtmlGenericControl errors = null;
protected event VoidVoid ErrorEvent;
protected event VoidVoid WarningEvent;
protected event VoidVoid SuccessEvent;Then I have methods defined there that work with the tag with the ID errors and, where appropriate, raise the right event. They look like this:
/// <summary>
/// This will be shown only for the most serious errors, when I want to strongly warn the user about something. It should make the user realize they should not try it again. I also raise the ErrorEvent event here, so in its handler I can put code that, for example, writes something to the EventLog, if one exists.
/// </summary>
/// <param name="message">
protected void Error(string message)
{
errors.Visible = true;
errors.InnerHtml = message;
errors.Attributes.Remove("class");
errors.Attributes.Add("class", "error");
if (ErrorEvent != null)
{
ErrorEvent();
}
}
/// <summary>
/// This will be used for most types of errors - whether something is not found in the DB or something fails, e.g. to save.
/// </summary>
/// <param name="message">
protected void Warning(string message)
{
errors.Visible = true;
errors.InnerHtml = message;
errors.Attributes.Remove("class");
errors.Attributes.Add("class", "warning");
if (WarningEvent != null)
{
WarningEvent();
}
}
/// <summary>
/// This will be used only when the user enters the page, to give them some information.
/// </summary>
/// <param name="message">
protected void Info(string message)
{
errors.Visible = true;
errors.InnerHtml = message;
errors.Attributes.Remove("class");
errors.Attributes.Add("class", "info");
}
/// <summary>
/// This will be used when an operation succeeds.
/// </summary>
/// <param name="message">
protected void Success(string message)
{
errors.Visible = true;
errors.InnerHtml = message;
errors.Attributes.Remove("class");
errors.Attributes.Add("class", "success");
if (SuccessEvent != null)
{
SuccessEvent();
}
}In a page derived from GgdagPage, I then assign the errors element to the parent class (they have the same name, so that if I happen to forget step 1, a NullReferenceException is thrown right at the start) and, if needed, hook up the event handlers, which are generated for me when I type “plus” + tab.
base.errors = errors;
ErrorEvent += new VoidVoid(EditCat_ErrorEvent);In the handler itself, I can then put, for example, what should happen after an error (what should be hidden, etc.):
void EditCat_ErrorEvent()
{
registerFieldsCat.Visible = false;
}Of course, I don’t forget to add the CSS styles, which I link in MasterPage.master (or another *.master)
/* The background must never be dark, because
otherwise it doesn't look nice. */
#errors
{
background-color: White;
border: 1px solid Lime;
padding: 5px 10px 5px 10px;
}
.success
{
color: Lime;
}
.error
{
color: Red;
}
.warning
{
color: Orange;
}
.info
{
color: Black;
}The result looks roughly like this (the page background should ideally be white or light colors with low saturation and possibly high brightness):
