Creo que el siguiente código podría ser una buena combinación de varias respuestas. Utiliza un servicio web para recuperar nuevas notificaciones y jquery para extraer notificaciones en un intervalo. Almacena las notificaciones en la sesión de los usuarios.
Lo primero es lo primero, nuestra clase simple "Mensaje" que representa un solo mensaje. Me di cuenta en su pregunta que tendría múltiples tipos de mensajes, así que quería asegurarme de proporcionar una solución que cubriera estos. Mi clase de mensaje tiene solo dos propiedades: Texto y Tipo. Tipo, en mi demostración, se utiliza como el color de fondo del mensaje.
public class Message
{
public string Text { get; set; }
public string Type { get; set; }
}
Siguiente es nuestra clase UserMessages que se encarga de guardar y recuperar mensajes. Guarda todos los mensajes en la sesión de los usuarios.
public class UserMessages
{
protected static string _messageSessionID = "userMessages";
public static List<Message> GetMessages()
{
var msg = HttpContext.Current.Session[_messageSessionID];
if (msg == null)
{
return new List<Message>();
}
//clear existing messages
HttpContext.Current.Session[_messageSessionID] = null;
//return messages
return (List<Message>)msg;
}
public static void AddMessage(Message message)
{
var msg = GetMessages();
msg.Add(message);
HttpContext.Current.Session[_messageSessionID] = msg;
}
}
Para mi demo decidí leer los messaages utilizando AJAX mediante la combinación de un servicio web ASP.Net, ScriptManager y jQuery.Aquí está mi servicio web:
--ASMX File--
<%@ WebService Language="C#" CodeBehind="~/App_Code/MessageService.cs" Class="UserNotification.MessageService" %>
--cs File--
namespace UserNotification
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class MessageService : System.Web.Services.WebService
{
public MessageService()
{
}
[WebMethod(EnableSession = true)]
public List<Message> GetMessages()
{
return UserMessages.GetMessages();
}
}
}
En mi página aspx he creado un scriptmanager con una referencia a mi servicio, un marcador de posición div para los mensajes y una interfaz de adición mensaje rápido y sucio:
<asp:ScriptManager runat="server">
<Services>
<asp:ServiceReference Path="~/MessageService.asmx" />
</Services>
</asp:ScriptManager>
<div>
<div id="msgArea">
</div>
<span>Add Message</span>
Text: <asp:TextBox ID="txtMessage" runat="server" />
<br />
Type: <asp:TextBox ID="txtType" runat="server" Text="yellow" />
<asp:Button ID="btnAdd" runat="server" Text="Add" onclick="btnAdd_Click" />
</div>
</form>
para apoyar la creación de mensajes que añaden t El siguiente método en el código detrás para manejar el botón haga clic en evento:
protected void btnAdd_Click(object sender, EventArgs e)
{
UserMessages.AddMessage(new Message() {Text = txtMessage.Text, Type = txtType.Text});
}
Ahora para la pieza importante. Para hacer la visualización real de los mensajes escribí el siguiente bloque de javascript (usando principalmente jquery, utilicé v1.4.1, pero puede usar la versión que desee). El temporizador se establece en un intervalo de 30 segundos. Esto significa que también espera 30 segundos antes de procesar la primera vez. Para procesar inmediatamente en la carga de la página, agregue CheckMessages();
justo antes de setInterval para realizar una verificación inmediata de la carga de la página. Dejar en el setInterval permitirá actualizaciones periódicas a los mensajes.
<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
setInterval('CheckMessages();', 30000);
});
function CheckMessages() {
UserNotification.MessageService.GetMessages(function (result) {
//alert('found ' + result.length.toString() + ' messages.');
$.each(result, function (i, e) {
var dv = $('<div />')
.css('background-color', e.Type)
.css('border', '4px solid white')
.css('color', 'white')
.css('text-align', 'center')
.append('<span>' + e.Text + '</span>')
.append(
$('<button />')
.text('Close')
.click(function() { $(this).parent().remove(); }));
$('#msgArea').append(dv);
});
}, function (e) { alert(e._message); });
}
</script>
Nota en el bloque anterior de código que utilizo e.Text, que coincide con el nombre de nuestra propiedad en el código, y e.type. e.Type es nuestro color de fondo especificado aquí, pero probablemente se utilizaría para otra cosa en la vida real. Además, en la vida real, todos esos atributos CSS estarían en una clase de CSS (probablemente una única clase de CSS para cada tipo de mensaje). Agregué un botón de "cerrar", no lo mencionaste pero pensé que la gente querría poder cerrar las notificaciones.
Una cosa genial acerca de esta implementación es que si en el futuro se da cuenta de que necesita almacenar mensajes NO en la sesión sino en, por ejemplo, una base de datos, esta implementación lo manejará sin problemas. Simplemente modifique UserMessages.GetMessages para extraer desde una ubicación db/other y ya está configurado. Además, puede configurarlo para manejar mensajes globales leyéndolos desde la memoria caché además de leer mensajes de usuario de la sesión.
http://msdn.microsoft.com/en-us/library/ms972429.aspx así como Session.Add ("Notificiations", myList); ¿Cómo voy a inicializar esa lista de "Notificaciones" y anexarla a todos lados? – tester
@tester: Agregué un código a mi respuesta anterior – citronas
impresionante. esto funcionó bien cuando hice 'Session'' HttpContext.Current.Session'. ¡Gracias! – tester