我将如何创建全局通知类?

时间:2011-06-20 17:51:54

标签: c# .net asp.net notifications

对于c#还有点新意,我需要在正确的方向上指点一些......

我希望在C#/ Asp.net中构建一个通知系统,它允许整个站点的不同方法将消息和消息类型添加到某个静态列表中,这些列表可以在下一页加载时循环。它类似于堆栈溢出如何在每个页面上加载成就的横幅通知(例如“你赢得了x徽章”,你获得了y徽章“)。任何想法我如何暴露一些其他人可能只是消息的全局方法。使用?

添加('消息','消息类型')

编辑:

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

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

4 个答案:

答案 0 :(得分:9)

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

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

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

  • 使您的网络应用程序看起来更有状态并“了解”服务器上的更改
  • 对不必要的页面刷新进行分配,这些页面刷新会破坏用户体验

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

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

当然,您需要谨慎对待会话或缓存中存储的内容。在脚下射击很容易。

答案 1 :(得分:6)

你可以写一个这样的类(我附近没有任何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 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上的通知)来调整此代码。要了解如何完成,您可以使用搜索。这里已经讨论了几个倍)

我希望这会对你有所帮助。

答案 2 :(得分:1)

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

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

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

我可以在这里给你一个示例代码,但是在我回到家之前我无法做到。

答案 3 :(得分:1)

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

首先,我们简单的“Message”类代表单个消息。我在你的问题中注意到你会有多种类型的消息,所以我想确保提供一个涵盖这些消息的解决方案。我的消息类只有两个属性:Text和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 webservice,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页面上,我创建了一个scriptmanager,其中包含对我的服务的引用,一个用于消息的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即可从db / other位置进行提取,然后进行设置。此外,除了从会话中读取用户消息之外,您还可以通过从缓存中读取全局消息来将其设置为处理全局消息。