Я реализовал следующим образом:
1. Создал JS класс AlertsContainer, у которого реализовал методы для добавления/удаления оповещений, увеличения/уменьшения счетчика оповещений.
2. При обновлении страницы - в Layout получаю на сервере последние оповещения и формирую с помощью razor - раздел [script], в котором в $( document ).ready() вызывая метод AlertsContainer.AddAlert( '@(alert.Message)', @(isReaded) ); - добавляю последние оповещения, и ставлю число непрочитанных.
3. Если на клиент приходит оповещение - вызываю опять AlertsContainer.AddAlert...
4. Сделал метод на клиенте для пометки оповещения как прочитанное - AlertsContainer.NotificationSetReaded: function (id) { ... } - там с помощью SignalR - сообщение уходит на сервер, уменьшая число непрочитанных и меняет CSS-class у оповещения.
Так и работаю с оповещениями, пока страница не обновится. Вроде без дублирования.
AddAlert - работает с Html.
$(function () {
AlertsContainer = {
AddAlert: function (notificationData, notificationName, id, level, created) {
var builder = [""];
builder.push("<li id='alert_" + id + "'");
builder.push(">");
if (self.level == "Error")
builder.push("<i class='fa fa-exclamation fa-fw'></i>");
.....
document.getElementById("alertsContainer").outerHTML = builder.join("")
},
AddUnreadCount: function (count) {
var oldCount = Number( $('#notificationsUnreadCount').html());
....
var newVal = oldCount + count;
$('#notificationsUnreadCount').html(newVal);
}
@foreach (var alert in alerts)
{
@: AlertsContainer.AddAlert(
@:'@(alert.Notification.NotificationName)',
@:'@(alert.UserNotification.Id)',
@:'@((byte?)alert.Notification.Level)',
@:'@(alert.UserNotification.Created)' ,
}