代码之家  ›  专栏  ›  技术社区  ›  Ahmad

在ASP.NET MVC Web应用程序中使用Signaler在数据库中插入或更新记录时无法通知用户

  •  0
  • Ahmad  · 技术社区  · 6 年前

    我想创建一个应用程序,可以在数据库中插入/更新或删除任何内容时通知用户。

    我使用了signaler和sql依赖,但在数据库发生更改时仍然没有收到任何通知。

    这是控制器:

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    
        public JsonResult GetNotificationContacts()
        {
            var notificationRegisterTime = Session["LastUpdated"] != null ? Convert.ToDateTime(Session["LastUpdated"]) : DateTime.Now;
            NotificationComponent NC = new NotificationComponent();
            var list = NC.GetContacts(notificationRegisterTime);
            //update session here for get only new added contacts (notification)
            Session["LastUpdate"] = DateTime.Now;
            return new JsonResult { Data = list, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }
    }
    

    这是startup.cs类

    namespace PushNotification
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                app.MapSignalR();
            }
        }
    }
    

    这是web.config文件中的连接字符串

    <connectionStrings>
        <add name="sqlConString" connectionString="data source=SHOAIB\SQLEXPRESS;initial catalog=MyPushNotification;integrated security=True;" />
        <add name="MyPushNotificationEntities2" connectionString="metadata=res://*/MyPushNotificationModel.csdl|res://*/MyPushNotificationModel.ssdl|res://*/MyPushNotificationModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=shoaib\sqlexpress;initial catalog=MyPushNotification;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
    </connectionStrings>
    

    这是我的应用程序中名为notificationhub的中心

    namespace PushNotification
    {
        public class NotificationHub : Hub
        {
            //public void Hello()
            //{
            //    Clients.All.hello();
            //}
        }
    }
    

    这是通知组件类

    namespace PushNotification
    {
        public class NotificationComponent
        {
            //Here we will add a function for register notification (will add sql dependency)
            public void RegisterNotification(DateTime currentTime)
            {
                string conStr = ConfigurationManager.ConnectionStrings["sqlConString"].ConnectionString;
                string sqlCommand = @"SELECT [ContactId],[ContactName],[ContactNo] from [dbo].[Contacts] where [AddedOn] > @AddedOn";
                //you can notice here I have added table name like this [dbo].[Contacts] with [dbo], its mendatory when you use Sql Dependency
                using (SqlConnection con = new SqlConnection(conStr))
                {
                    SqlCommand cmd = new SqlCommand(sqlCommand, con);
                    cmd.Parameters.AddWithValue("@AddedOn", currentTime);
                    if (con.State != System.Data.ConnectionState.Open)
                    {
                        con.Open();
                    }
                    cmd.Notification = null;
                    SqlDependency sqlDep = new SqlDependency(cmd);
                    sqlDep.OnChange += sqlDep_OnChange;
                    //we must have to execute the command here
                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        // nothing need to add here now
                    }
                }
            }
    
            void sqlDep_OnChange(object sender, SqlNotificationEventArgs e)
            {
                if (e.Type == SqlNotificationType.Change)
                {
                    SqlDependency sqlDep = sender as SqlDependency;
                    sqlDep.OnChange -= sqlDep_OnChange;
    
                    //from here we will send notification message to client
                    var notificationHub = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
                    notificationHub.Clients.All.notify("added");
    
                    //re-register notification
                    RegisterNotification(DateTime.Now);
    
                }
            }
    
            public List<Contact> GetContacts(DateTime afterDate)
            {
                using (MyPushNotificationEntities2 dc = new MyPushNotificationEntities2())
                {
                    return dc.Contacts.Where(a => a.AddedOn > afterDate).OrderByDescending(a => a.AddedOn).ToList();
                }
            }
        }
    }
    

    我在global.asax文件中做了如下更改

    namespace PushNotification
    {
        public class MvcApplication : System.Web.HttpApplication
        {
            string con = ConfigurationManager.ConnectionStrings["sqlConString"].ConnectionString;
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                //here in Application Start we will start Sql Dependency
                SqlDependency.Start(con);
            }
    
            protected void Session_Start(object sender, EventArgs e)
            {
                NotificationComponent NC = new NotificationComponent();
                var currentTime = DateTime.Now;
                HttpContext.Current.Session["LastUpdated"] = currentTime;
                NC.RegisterNotification(currentTime);
            }
            protected void Application_End()
            {
                //here we will stop Sql Dependency
                SqlDependency.Stop(con);
            }
        }
    }
    

    最后这是布局文件和更改

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - My ASP.NET Application</title>
    <link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
    <link href="~/Content/bootstrap.min.css" rel="stylesheet" />
    <script src="~/Scripts/modernizr-2.6.2.js"></script>
    </head>
    <body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">  
                <span class="noti glyphicon glyphicon-bell"><span class="count">&nbsp;</span></span>            
                <div class="noti-content">
                    <div class="noti-top-arrow"></div>
                    <ul id="notiContent"></ul>
                </div>
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("Application name", "Index", "Home", null, new { @class = "navbar-brand" })
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
    
                </ul>
            </div>
        </div>
    </div>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
        </footer>
    </div>
    @* Add Jquery Library *@
    <script src="~/Scripts/jquery-2.2.3.min.js"></script>
    <script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script>
    <script src="/signalr/hubs"></script>
    <script src="~/Scripts/bootstrap.min.js"></script>
    @* Add css  *@
    <link href="~/Content/bootstrap.min.css" rel="stylesheet" />
    <style type="text/css">
        /*Added css for design notification area, you can design by your self*/
        /* COPY css content from youtube video description*/
        .noti-content{
            position:fixed;
            right:100px;
            background:#e5e5e5;
            border-radius:4px;
            top:47px;
            width:250px;
            display:none;
            border: 1px solid #9E988B;
        }
        ul#notiContent{
            max-height:200px;
            overflow:auto;
            padding:0px;
            margin:0px;
            padding-left:20px;
        }
            ul#notiContent li {
                margin:3px;
                padding:6px;
                background:#fff;
            }
    
            .noti-top-arrow{
                border-color:transparent;
                border-bottom-color:#F5DEB3;
                border-style:dashed dashed solid;
                border-width: 0 8.5px 8.5px;
                position:absolute;
                right:32px;
                top:-8px;
            }
            span.noti{
                color:#FF2323;
                margin:15px;
                position:fixed;
                right:100px;
                font-size:18px;
                cursor:pointer;
            }
            span.count{
                position:relative;
                top:-3px;
            }
    </style>
    
    @* Add jquery code for Get Notification & setup signalr *@
    <script type="text/javascript">
        $(function () {
            // Click on notification icon for show notification
            $('span.noti').click(function (e) {
                e.stopPropagation();
                $('.noti-content').show();
                var count = 0;
                count = parseInt($('span.count').html()) || 0;
                //only load notification if not already loaded
                if (count > 0) {
                    updateNotification();
                }
                $('span.count', this).html('&nbsp;');
            })
            // hide notifications
            $('html').click(function () {
                $('.noti-content').hide();
            })
            // update notification 
            function updateNotification() {
                $('#notiContent').empty();
                $('#notiContent').append($('<li>Loading...</li>'));
    
                $.ajax({
                    type: 'GET',
                    url: '/home/GetNotificationContacts',
                    success: function (response) {
                        $('#notiContent').empty();
                        if (response.length  == 0) {
                            $('#notiContent').append($('<li>No data available</li>'));
                        }
                        $.each(response, function (index, value) {
                            $('#notiContent').append($('<li>New contact : ' + value.ContactName + ' (' + value.ContactNo + ') added</li>'));
                        });
                    },
                    error: function (error) {
                        console.log(error);
                    }
                })
            }
            // update notification count
            function updateNotificationCount() {
                var count = 0;
                count = parseInt($('span.count').html()) || 0;
                count++;
                $('span.count').html(count);
            }
            // signalr js code for start hub and send receive notification
            var notificationHub = $.connection.notificationHub;
            $.connection.hub.start().done(function () {
                console.log('Notification hub started');
            });
    
            //signalr method for push server message to client
            notificationHub.client.notify = function (message) {
                if (message && message.toLowerCase() == "added") {
                    updateNotificationCount();
                }
            }
    
        })
    </script>
    </body>
    </html>
    

    我的数据库在sqlservermanagementstudio中,当我插入一个新记录时,前端不会收到任何通知。

    如果你在这方面有专长,请帮忙。 多谢提前。

    0 回复  |  直到 6 年前