Как мне создать глобальный класс уведомлений? - PullRequest
8 голосов
/ 20 июня 2011

Все еще немного новичок в c #, и мне нужны некоторые указатели в правильном направлении с этим ..

Я хочу создать систему уведомлений на C # / Asp.net, которая позволит различным методам по всему сайту добавлять сообщения и типы сообщений в некоторый статический список, который можно перебрать при следующей загрузке страницы. Это было бы похоже на то, как переполнение стека делает баннеры для уведомлений о достижениях при каждой загрузке страницы (например, «вы заработали х значок», вы заработали у значок «). Любая идея, как я могу представить какой-то глобальный метод, чтобы другие могли просто отправить сообщение. добавить ('message', 'тип сообщения') с?

Edit:

Было предложено использовать Session.Add("Notificiations", myList); для хранения сообщений.

Как / где бы я мог инициализировать этот список "Уведомления", а затем сделать list.add () где-нибудь еще?

Ответы [ 4 ]

9 голосов
/ 20 июня 2011

Показывать всплывающие баннеры в верхней части страницы на постбэках довольно аккуратно, но даже круче, чем при использовании jQuery и ajax для периодических проверок с сервером на предмет изменения состояния чего-либо, или в вашем случаеу пользователя есть «новые» сообщения.

Это действительно прекрасно работает, когда на веб-сервере работает какой-то асинхронный процесс, и вы не знаете, сколько времени это займет (или вы точно знаете, что это займет очень много времени), итак что вы не хотите, чтобы браузер вашего клиента был привязан в ожидании этого.Используя javascript и window.setInterval, вы можете настроить функцию на запуск каждые 30 секунд (или как вам угодно), и затем вы сказали, что функция делает сообщение ajax на сервере, чтобы увидеть, завершен ли асинхронный процесс.В вашем случае пост ajax просто будет спрашивать сервер, есть ли у пользователя какие-либо «новые» сообщения.Если у пользователя есть новые сообщения, то просто использовать jQuery для отображения скрытого элемента div на странице, информирующего пользователя о том, что у него есть новые сообщения.

Это немного сложное решение, и оно может быть непосильным для любителя, но оно того стоит!

  • Делает ваше веб-приложение более насыщенным и «осведомленным»изменений на сервере
  • Обойтись без ненужных обновлений страниц, которые могут нарушить работу пользователя

И, как уже отмечали другие, лучшим местом для хранения «глобальной» информации обычно являетсясессия (просто обратите внимание на ограниченную сессию). MSDN ASP.NET Session State

Однако, если это данные, к которым должен обращаться каждый клиент, вы можете сохранить их в кеше приложения. Кэширование ASP.NET

Конечно, вы должны проявлять осторожность с тем, сколько вы храните в сеансе или в кэше.Легко выстрелить себе в ногу.

6 голосов
/ 20 июня 2011

Вы можете написать такой класс (у меня нет IDE рядом со мной, поэтому я надеюсь, что код скомпилируется):

public class MessageHelper
{
    protected const String sessionName = "messages_session";
    public List<String> Messages 
    {
        get 
        {
            List<string> list;
            if (Session[sessionName] != null)
            {
                list = (List<string>)Session[sessionName];
            }
            else 
            {
                list = new List<string>();
            }
            Session[sessionName] = list;
            return list;
        }
        set 
        {
            Session[sessionName] = value;
        }
    }

    public void AddMessage(String message) 
    {
        List<String> list = this.Messages;
        list.Add(message);
        this.Messages = list;
    }

}

Чтобы добавить сообщение, вы должны сделать:

MessageHelper messageHelper = new MessageHelper();
messageHelper.AddMessage("hello world");

(Эти сообщения хранятся в сеансе, то есть для конкретного пользователя);

Предположим, у вас есть литерал на главной странице, где вы хотите отображать свои сообщения:

<asp:Literal ID="litMessages" runat="server" />

В вашей мастер-странице вы бы добавили обработчик событий OnInit :

protected override void OnInit(EventArgs e)
{
  MessageHelper messageHelper = new MessageHelper();
  String output = string.Empty;
  foreach(String message in messageHelper.Messages)
  {
    output += String.Format("{0}<br />", message);
  }
  this.litMessages.Text = output;

}

Это должно дать вам общее представление о том, как вы можете хранить и отображать сообщения. Конечно, вы можете изменить этот код, добавив метод удаления сообщений или приятные побочные эффекты клиента (например, уведомления здесь, в StackOverflow. Чтобы узнать, как это сделать, вы можете использовать поиск. Он обсуждался здесь раз)

Надеюсь, это поможет вам.

1 голос
/ 27 июня 2011

Я думаю, что приведенный ниже код может быть хорошей комбинацией различных ответов.Он использует веб-сервис для получения новых уведомлений и JQuery для извлечения уведомлений на интервале.Он хранит уведомления в сеансе пользователя.

Во-первых, наш простой класс «Message», который представляет одно сообщение.В вашем вопросе я заметил, что у вас будет несколько типов сообщений, поэтому я хотел бы обеспечить решение, которое охватывает это.Мой класс сообщений имеет только два свойства: текст и тип.Тип, в моей демонстрации, используется в качестве цвета фона сообщения.

public class Message
{
    public string Text { get; set; }
    public string Type { get; set; }
}

Далее следует наш класс UserMessages, который обрабатывает сохранение и поиск сообщений.Он сохраняет все сообщения в пользовательском сеансе.

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;
    }
}

Для своей демонстрации я решил прочитать сообщения, используя AJAX, объединив веб-сервис ASP.Net, ScriptManager и jquery.Вот мой веб-сервис:

- Файл ASMX -

<%@ WebService Language="C#" CodeBehind="~/App_Code/MessageService.cs" Class="UserNotification.MessageService" %>

- Файл CS -

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();
        }
    }
}

На моей странице aspx я создал скрипт-менеджер сссылка на мой сервис, местозаполнитель div для сообщений и интерфейс быстрого и грязного добавления сообщений:

    <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>

Для поддержки создания сообщений в код добавлен следующий метод для обработки события нажатия кнопки:

protected void btnAdd_Click(object sender, EventArgs e)
{
    UserMessages.AddMessage(new Message() {Text = txtMessage.Text, Type = txtType.Text});
}

Теперь о важной части.Для реального отображения сообщений я написал следующий блок javascript (используя в основном jquery, я использовал v1.4.1, но вы можете использовать любую версию, какую пожелаете).Таймер установлен с интервалом 30 секунд.Это означает, что он также ожидает 30 секунд перед первой обработкой.Чтобы сразу обработать загрузку страницы, добавьте CheckMessages(); прямо перед setInterval, чтобы выполнить немедленную проверку загрузки страницы.Выход из setInterval позволит периодически обновлять сообщения.

<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>

Обратите внимание, что в приведенном выше блоке кода я использую e.Text, который соответствует имени нашего свойства в коде, и e.Type.e.Type - это наш заданный цвет фона, но он, вероятно, будет использоваться для чего-то другого в реальной жизни.Кроме того, в реальной жизни все эти атрибуты CSS были бы в классе CSS (вероятно, один класс CSS для каждого типа сообщения).Я добавил кнопку «Закрыть», вы не упомянули об этом, но я подумал, что люди захотят иметь возможность закрыть уведомления.

Одна классная вещь в этой реализации - то, что в будущем вы понимаете, что вам нужночтобы хранить сообщения НЕ в сеансе, а, скажем, в базе данных, эта реализация будет обрабатывать его гладко.Просто измените UserMessages.GetMessages, чтобы вытащить из БД / другое место, и все готово.Кроме того, вы можете настроить его для обработки глобальных сообщений, читая их из кэша в дополнение к чтению пользовательских сообщений из сеанса.

1 голос
/ 24 июня 2011

Я бы предложил определить это как службу, которая может быть реализована в виде wcf / веб-службы или интерфейса внутри вашего веб-приложения.

Использование этой функции в качестве службы имеет несколько преимуществ, в том числе масштабируемость, доступность и т. Д. Например, клиент, использующий ваше приложение iphone, отправляет сообщение, и другой клиент, использующий ваш веб-сайт, может это увидеть.

если вы предпочитаете второй подход, вам нужно использовать DI-фреймворк, такой как Ninject, и убедиться, что DI / Ioc-фреймворки применяют одноэлементный шаблон к экземпляру.

Я могу дать вам пример кода здесь, но я не смогу сделать это, пока не вернусь домой.

...