【问题标题】:how would I go about creating a global notification class?我将如何创建一个全局通知类?
【发布时间】:2011-06-20 17:51:54
【问题描述】:

对 c# 还是有点陌生​​,我需要一些指向正确方向的指针..

我想在 C#/Asp.net 中构建一个通知系统,该系统将允许整个站点的不同方法将消息和消息类型添加到可以在下一页加载时循环的静态列表中。这类似于堆栈溢出如何在每个页面加载时对成就进行横幅通知(例如,“您获得了 x 徽章”,您获得了 y 徽章)。知道我如何公开一些其他人可以发送消息的全局方法。 add('message', 'message type') with?

编辑:

有人建议我使用Session.Add("Notificiations", myList); 来存储消息。

我将如何/在哪里初始化“通知”列表,然后在其他任何地方执行 list.add()?

【问题讨论】:

    标签: c# .net asp.net notifications


    【解决方案1】:

    在回发的页面顶部显示弹出横幅非常简洁,但比使用 jQuery 和 ajax 定期检查服务器以查看某些内容的状态是否已更改或在您的情况下是否更改更酷用户有任何“新”消息。

    当您在 Web 服务器上运行一些异步进程并且您不知道它需要多长时间(或者您确定这将需要很长时间)并且您不知道时,这确实非常有用'不希望您的客户的浏览器被捆绑等待它。使用 javascript 和 window.setInterval 您可以将函数设置为每 30 秒发生一次(或任何您喜欢的),然后您已经说过该函数对服务器执行 ajax 发布以查看异步过程是否完成。在您的情况下,ajax 帖子只是询问服务器用户是否有任何“新”消息。如果用户确实有新消息,那么使用 jQuery 在页面上显示一些隐藏的 div 通知用户他们有新消息是一件简单的事情。

    这是一个有点复杂的解决方案,可能超出了业余爱好者的技能,但收获是值得的!

    • 让您的网络应用看起来更有状态,并“感知”服务器上的变化
    • 无需进行可能会破坏用户体验的不必要的页面刷新

    正如其他人已经指出的那样,存储“全局”信息的最佳位置通常是 Session(只需注意 Session 的有限范围)。 MSDN ASP.NET Session State

    但是,如果是每个客户端都需要访问的数据,那么您可以将其存储在应用程序缓存中。 ASP.NET Caching

    当然,您需要谨慎对待在 Session 或 Cache 中存储的数量。打自己的脚很容易。

    【讨论】:

      【解决方案2】:

      你可以这样写一个类(我附近没有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" />
      

      在您的 MasterPage 中,您可以添加 OnInit Eventhandler:

      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 上的通知。要了解这是如何完成的,您可以使用搜索。这里已经讨论了几个次)

      希望对你有帮助。

      【讨论】:

      • msdn.microsoft.com/en-us/library/ms972429.aspx 就像 Session.Add("Notifications", myList);我将如何初始化该“通知”列表并将其附加到其他任何地方?
      • 太棒了。当我制作 Session HttpContext.Current.Session 时,效果很好。谢谢!
      • @tester:很高兴我能帮上忙。您将我的答案标记为已接受,所以我猜您也愿意给我赏金? ;)
      • 啊,是的,我可以发誓我点击了它。恭喜!
      【解决方案3】:

      我建议将其定义为可以实现为 wcf/web 服务或 web 应用程序中的接口的服务。

      将此功能作为服务有几个好处,包括可扩展性、可用性等。例如,使用您的 iphone 应用程序的客户端发送消息,而使用您的网站的另一个客户端可以看到。

      如果您更喜欢第二种方法,则需要使用 DI 框架(例如 Ninject)并确保 DI/Ioc 框架在实例上应用单例模式。

      我可以在这里给你一个示例代码,但直到我回到家我才能做到。

      【讨论】:

        【解决方案4】:

        我认为我下面的代码可能是各种答案的良好组合。它使用 Web 服务来检索新通知,并使用 jquery 来按时间间隔拉取通知。它将通知存储在用户会话中。

        首先,我们简单的“消息”类表示一条消息。我在你的问题中注意到你会有多种类型的消息,所以我想确保提供一个涵盖这些的解决方案。我的消息类只有两个属性:文本和类型。在我的演示中,Type 被用作消息的背景颜色。

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

        对于我的演示,我决定通过结合 ASP.Net Web 服务、ScriptManager 和 jquery 来使用 AJAX 读取消息。这是我的网络服务:

        --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 秒。要在页面加载时立即处理,请在 setInterval 之前添加 CheckMessages(); 以立即检查页面加载。保留在 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 以从数据库/其他位置拉取即可。此外,除了从会话中读取用户消息之外,您还可以将其设置为通过从缓存中读取全局消息来处理全局消息。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-09-27
          • 2022-06-11
          • 2017-02-20
          • 1970-01-01
          • 2019-09-09
          • 1970-01-01
          • 2022-07-12
          • 1970-01-01
          相关资源
          最近更新 更多