我该如何创建一个全局通知类

本文关键字:一个 全局 通知 创建 何创建 | 更新日期: 2023-09-27 17:59:48

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

我想在C#/Asp.net中建立一个通知系统,允许网站上的不同方法将消息和消息类型添加到一些静态列表中,这些静态列表可以在下一页加载时循环使用。这将类似于堆栈溢出如何加载每个页面上成就的横幅通知(例如"你赢得了x徽章",你赢得了y徽章")。你知道我如何暴露一些全局方法,其他人可以直接使用message.add('message','messagetype')吗?

编辑:

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

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

我该如何创建一个全局通知类

在回发时在页面顶部显示弹出横幅非常整洁,但比这更酷的是使用jQuery和ajax定期检查服务器,看看某个东西的状态是否发生了变化,或者在您的情况下,用户是否有任何"新"消息。

当你有一些异步进程在网络服务器上运行,但你不知道它需要多长时间(或者你肯定知道它需要很长时间),所以你不希望你的客户端浏览器被束缚在等待它的时候,这真的很好。使用javascript和window.setInterval,你可以设置一个函数,每30秒发生一次(或者你喜欢的任何事情),然后,您让所述函数对服务器执行ajax post,以查看异步进程是否完成。在您的情况下,ajax帖子只是询问服务器用户是否有任何"新"消息。如果用户确实有新消息,那么只需使用jQuery在页面上显示一些隐藏的div,通知用户他们有新消息。

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

  • 使您的web应用程序看起来更有状态,并"意识到"服务器上的更改
  • 免除了不必要的页面刷新,这些刷新往往会破坏用户体验

正如其他人已经指出的,存储"全局"信息的最佳位置通常是会话(只需注意会话的有限范围)。MSDN-ASP。NET会话状态

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

当然,您需要谨慎处理会话或缓存中的存储量。射中自己的脚很容易。

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

我希望这对你有帮助。

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

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

如果您喜欢第二种方法,则需要使用诸如Ninject之类的DI框架,并确保DI/Ioc框架在实例上应用singleton模式。

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

我认为下面的代码可能是各种答案的完美组合。它使用web服务来检索新的通知,并使用jquery来每隔一段时间提取通知。它将通知存储在用户会话中。

首先,我们的简单"Message"类表示单个消息。我在你的问题中注意到你会有多种类型的消息,所以我想确保提供一个涵盖这些的解决方案。我的消息类只有两个属性:Text和Type。在我的演示中,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;
    }
}

在我的演示中,我决定使用AJAX结合ASP.Net Web服务、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秒。要立即处理页面加载,请在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修改为从数据库/其他位置拉取即可。此外,除了从会话中读取用户消息外,您还可以将其设置为通过从缓存中读取全局消息来处理全局消息。