简体   繁体   English

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

[英]how would I go about creating a global notification class?

Still a bit new to c# and I'm in need of some pointers in the right direction with this.. 对于c#还有点新意,我需要在正确的方向上指点一些..

I want build a notification system in C#/Asp.net that will allow different methods all over the site to add messages and message types to some static list that can be looped through on the next page load. 我想在C#/ Asp.net中构建一个通知系统,它允许整个站点的不同方法将消息和消息类型添加到一些静态列表中,这些列表可以在下一页加载时循环。 It would be similar to how stack overflow does the banner notifications for achievements on each page load (eg "you earned x badge", you earned y badge"). Any idea how I might expose some global method that others could just go message.add('message', 'message type') with? 它类似于堆栈溢出如何在每个页面上加载成就的横幅通知(例如“你赢得了x徽章”,你获得了y徽章“)。任何想法我如何暴露一些其他人可能只是消息的全局方法。添加('消息','消息类型')?

Edit: 编辑:

It's been suggested that I use Session.Add("Notificiations", myList); 有人建议我使用Session.Add("Notificiations", myList); to store the messages. 存储消息。

How/where would I go about initializing that "Notifications" list then do list.add() everywhere else? 我将如何/在哪里初始化“通知”列表然后在其他地方执行list.add()?

Showing popup banners at the top of the page on postbacks is pretty neat, but even cooler than that is using jQuery and ajax to do periodic checks with the server to see if the state of something has changed, or in your case if the user has any "new" messages. 在回发页面顶部显示弹出式横幅非常简洁,但更酷的是使用jQuery和ajax定期检查服务器以查看某些内容是否已更改,或者在您的情况下是否有用户任何“新”消息。

This really works great when you have some asynchronous process running on the web server and you don't know how long it'll take (or you know for certain that it's going to take a real long time) and so you don't want your client's browser being tied up waiting for it. 当您在Web服务器上运行某个异步进程并且您不知道它需要多长时间(或者您确定它将花费很长时间)并且您不希望这样做时,这确实很有效。你的客户的浏览器正在等待它。 Using javascript and window.setInterval you can set a function to occur every 30 seconds (or whatever you like), and you then have said function do an ajax post against the server to see if the asynchronous process is complete. 使用javascript和window.setInterval你可以设置一个每30秒发生一次的函数(或者你喜欢的任何东西),然后你说这个函数对服务器做一个ajax发布,看看异步过程是否完成。 In your case the ajax post would simply be asking the server if the user has any "new" messages. 在您的情况下,ajax帖子只是询问服务器用户是否有任何“新”消息。 If the user does have new messages then it's a simple matter of using jQuery to display some hidden div on the page informing the user that they have new messages. 如果用户确实有新消息,那么使用jQuery在页面上显示一些隐藏的div通知用户他们有新消息是一件简单的事情。

It's a bit of a complicated solution and might be beyond the skills of an amateur, but the gains are worth it! 这是一个复杂的解决方案,可能超出业余爱好者的技能,但收益是值得的!

  • Makes your web app seem more stateful and "aware" of changes on the server 使您的Web应用程序看起来更有状态并“了解”服务器上的更改
  • Dispenses with needless page refreshes that tend to disrupt the user experience 不必要的页面刷新的分配,往往会破坏用户体验

And as others have already noted, the best place to store "global" information is usually the Session (just note the limited scope of the Session). 正如其他人已经指出的那样,存储“全局”信息的最佳位置通常是会话(仅注意会话的有限范围)。 MSDN ASP.NET Session State MSDN ASP.NET会话状态

However, if it is data that needs to be accessed by every client then you can store it in the application Cache. 但是,如果是每个客户端都需要访问的数据,则可以将其存储在应用程序缓存中。 ASP.NET Caching ASP.NET缓存

Of course, you'll want to exercise caution with how much you're storing in either the Session or the Cache. 当然,您需要谨慎对待您在会话或缓存中存储的数量。 It's easy to shoot yourself in the foot. 用脚射击自己很容易。

You can write a class like this (I don't have any IDE near me, so I hope the code will compile): 你可以写一个这样的类(我附近没有任何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;
    }

}

To add a message, you would do: 要添加消息,您可以执行以下操作:

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

(These messages are stored in the session, meaning user specific); (这些消息存储在会话中,意味着用户特定);

Let's assume you have literal in your masterpage, where you want to display your messages: 假设您的主页中有文字,您要在其中显示您的消息:

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

In your MasterPage you would add the OnInit Eventhandler : 在您的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;

}

This should give you a basic overview, how you can store and display the messages. 这应该为您提供基本概述,如何存储和显示消息。 Of course you can adjust this code, either by adding a method for deleting messages, or nice client side effects (like the notifications here on StackOverflow. To find out how that is done, you can use the search. It has been discussed here several times) 当然,您可以通过添加删除消息的方法或良好的客户端副作用(如StackOverflow上的通知)来调整此代码。要了解如何完成,您可以使用搜索。这里已经讨论了几个次)

I hope this helps you. 我希望这可以帮助你。

I would suggest to define this as a service which can be implemented as a wcf/web service or an interface within you web app. 我建议将其定义为可以作为wcf / web服务或web应用程序中的界面实现的服务。

Having this feature as a service has couple of benefits including scalability, availability, and etc. As an example, a client using your iphone app sends the message and another client using your web site can see that. 将此功能作为服务具有几个好处,包括可扩展性,可用性等。例如,使用您的iphone应用程序的客户端发送消息,而使用您的网站的另一个客户端可以看到。

if you prefer the 2nd approach, you need to use a DI framework such as Ninject and make sure that DI/Ioc frameworks applies singleton pattern on the instance. 如果你更喜欢第二种方法,你需要使用一个DI框架,比如Ninject,并确保DI / Ioc框架在实例上应用单例模式。

I can give you an sample code here, but I can't do it until I get back home. 我可以在这里给你一个示例代码,但在我回到家之前我不能这样做。

I think the code I have below might be a good combination of the various answers. 我认为我下面的代码可能是各种答案的良好组合。 It uses a web service to retrieve new notifications and jquery to pull notifications on an interval. 它使用Web服务检索新通知和jquery以在一定时间间隔内提取通知。 It stores the notifications in the users session. 它将通知存储在用户会话中。

First things first, our simple "Message" class which represents a single message. 首先,我们简单的“Message”类代表单个消息。 I noticed in your question that you would have multiple types of messages so i wanted to make sure to provide a solution that covered ths. 我在你的问题中注意到你会有多种类型的消息,所以我想确保提供一个涵盖这些消息的解决方案。 My message class has only two properties: Text and Type. 我的消息类只有两个属性:Text和Type。 Type, in my demo, is used as the background color of the message. 在我的演示中,键入用作消息的背景颜色。

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

Next is our UserMessages class which handles message saving and retrieval. 接下来是我们的UserMessages类,它处理消息保存和检索。 It saves all messages to the users session. 它将所有消息保存到用户会话。

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

For my demo I decided to read the messaages using AJAX by combining an ASP.Net webservice, ScriptManager, and jquery. 对于我的演示,我决定通过组合ASP.Net webservice,ScriptManager和jquery来阅读使用AJAX的消息。 Here is my webservice: 这是我的网络服务:

--ASMX File-- --ASMX文件 -

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

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

On my aspx page I created a scriptmanager with a reference to my service, a div placeholder for messages and a quick and dirty message adding interface: 在我的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>

To support message creation I added the following method in code behind to handle the button click event: 为了支持消息创建,我在代码后面添加了以下方法来处理按钮单击事件:

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

Now for the important piece. 现在是重要的一块。 To do the actual displaying of the messages I wrote the following block of javascript (using mostly jquery, I used v1.4.1, but you can use whichever version you wish). 为了实际显示消息,我编写了以下javascript块(主要使用jquery,我使用v1.4.1,但你可以使用你想要的任何版本)。 The timer is set on a 30 second interval. 定时器设置为30秒间隔。 This means that it waits 30 seconds before processing the first time also. 这意味着它在第一次处理之前等待30秒。 To process immediately on page load add CheckMessages(); 要在页面加载时立即处理,请添加CheckMessages(); right before the setInterval to perform an immediate check on page load. 就在setInterval之前,立即检查页面加载。 Leaving in the setInterval will allow for periodic updates to messages. 离开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>

Note in the above block of code that I use e.Text, which matches the name of our property in code, and e.Type. 请注意上面的代码块,我使用e.Text,它与代码中的属性名称和e.Type相匹配。 e.Type is our specified as our background color here but would probably be used for something else in real life. e.Type是我们在这里指定的背景颜色,但可能会用于现实生活中的其他东西。 Also, in real life all of those CSS attributes would be in a CSS class (probably a single CSS class for each message type). 此外,在现实生活中,所有这些CSS属性都将位于CSS类中(可能是每种消息类型的单个CSS类)。 I added a "close" button, you didn't mention it but I figured people would want to be able to close the notifications. 我添加了一个“关闭”按钮,你没有提到它,但我想人们希望能够关闭通知。

One cool thing about this implementation is that if down the road you realize you need to store messages NOT in the session but in, say, a database, this implementation will handle it smoothly. 关于这个实现的一个很酷的事情是,如果你知道你需要在会​​话中而不是在数据库中存储消息,这个实现将顺利处理它。 Just modify UserMessages.GetMessages to pull from a db/other location and you are set. 只需修改UserMessages.GetMessages即可从db / other位置进行提取,然后进行设置。 Additionally you could set it up to handle global messages by reading them from the cache in addition to reading user messages from the session. 此外,您可以将其设置为通过从缓存中读取全局消息来处理全局消息,此外还可以从会话中读取用户消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何创建外部网址监视器? - How would i go about creating a external url monitor? 我将如何创建ReturnAlteredObject扩展方法? - How would I go about creating a ReturnAlteredObject extension method? 我将如何 go 关于以另一种形式获取全局变量值? - How would I go About Getting a Global Variables value in another form? 我该如何进行单元测试呢? - How would I go about unit testing this? Unity:我将如何为无尽的亚军游戏创建一个加电系统? [等候接听] - Unity: How would I go about creating a power up system into my endless runner game? [on hold] 我将如何在 EF Core 中创建这种多对多关系? - How would I go about creating this many-to-many relationship in EF Core? 我将如何创建文本框项目列表以用于其他方法? - How would I go about creating a list of Textbox items to use in other methods? 我将如何使用OpenTK C#创建六边形棱镜? - How would I go about creating a hexagonal prism using OpenTK C#? 我将如何使用数据库创建登录表单以进行检查? - How would I go about creating a login form using a database for a check? 我该如何为我的随机数字猜谜游戏C#创建赢数和猜数 - How would i go about creating a win count and guess count for my random number guessing game C#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM