温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

通过 SignalR 类库,实现 ASP.NET MVC 的实时通信

发布时间:2020-07-28 17:02:00 来源:网络 阅读:489 作者:OneAPM123 栏目:编程语言

在本文中,您将学到在现有 ASP.NET MVC 框架的 CRUD 项目中,如何使用 SignalR 类库,显示来自数据库的实时更新。在这一主题中,我们将重点放在在现有 ASP.NET MVC 框架的 CRUD 项目中,如何使用 SignalR 类库,显示来自数据库的实时更新。 本文系国内 ITOM 管理平台 OneAPM 工程师编译整理。

本主题有以下两个步骤:

  1. 我们将创建一个示例应用程序来执行 CRUD 操作。

  2. 我们将使用 SignalR 类库让应用实时。

那些不熟悉 SignalR 的,请访问我以前有关 SignalR 概述 的文章。

第一步:

我们需要创建一个名为 CRUD_Sample 的数据库。在示例数据库中创建一个名为 Customer 的表。

CREATE TABLE [dbo].[Customer](     [Id] [bigint] IDENTITY(1,1)NOTNULL,      [CustName] [varchar](100)NULL,       [CustEmail] [varchar](150)NULL  )

存储过程

USE [CRUD_Sample]   GO   /****** Object:  StoredProcedure [dbo].[Delete_Customer]    Script Date: 12/27/2015 1:44:05 PM ******/   SETANSI_NULLSON   GO   SETQUOTED_IDENTIFIERON   GO   -- =============================================   -- Author:      <Author,,Name>   -- Create date: <Create Date,,>   -- Description: <Description,,>   -- =============================================   CREATE PROCEDURE [dbo].[Delete_Customer]       -- Add the parameters for the stored procedure here        @Id Bigint   AS   BEGIN       -- SET NOCOUNT ON added to prevent extra result sets from       -- interfering with SELECT statements.       SETNOCOUNTON;   -- Insert statements for procedure here       DELETE FROM [dbo].[Customers] WHERE [Id] = @Id       RETURN 1   END   GO   /****** Object:  StoredProcedure [dbo].[Get_Customer]    Script Date: 12/27/2015 1:44:05 PM ******/   SETANSI_NULLSON   GO   SETQUOTED_IDENTIFIERON   GO   -- =============================================   -- Author:      <Author,,Name>   -- Create date: <Create Date,,>   -- Description: <Description,,>   -- =============================================   CREATE PROCEDURE [dbo].[Get_Customer]        -- Add the parameters for the stored procedure here       @Count INT   AS   BEGIN       -- SET NOCOUNT ON added to prevent extra result sets from       -- interfering with SELECT statements.       SETNOCOUNTON;   -- Insert statements for procedure here       SELECT top(@Count)*FROM [dbo].[Customers]   END   GO   /****** Object:  StoredProcedure [dbo].[Get_CustomerbyID]    Script Date: 12/27/2015 1:44:05 PM ******/   SETANSI_NULLSON   GO   SETQUOTED_IDENTIFIERON   GO   -- =============================================   -- Author:      <Author,,Name>   -- Create date: <Create Date,,>   -- Description: <Description,,>   -- =============================================   CREATE PROCEDURE [dbo].[Get_CustomerbyID]        -- Add the parameters for the stored procedure here       @Id BIGINT   AS   BEGIN       -- SET NOCOUNT ON added to prevent extra result sets from       -- interfering with SELECT statements.       SETNOCOUNTON;   -- Insert statements for procedure here       SELECT*FROM [dbo].[Customers]       WHERE Id=@Id   END   GO   /****** Object:  StoredProcedure [dbo].[Set_Customer]    Script Date: 12/27/2015 1:44:05 PM ******/   SETANSI_NULLSON   GO   SETQUOTED_IDENTIFIERON   GO   -- =============================================   -- Author:      <Author,,Name>   -- Create date: <Create Date,,>   -- Description: <Description,,>   -- =============================================   CREATE PROCEDURE [dbo].[Set_Customer]       -- Add the parameters for the stored procedure here        @CustNameNvarchar(100)       ,@CustEmailNvarchar(150)   AS   BEGIN       -- SET NOCOUNT ON added to prevent extra result sets from       -- interfering with SELECT statements.       SETNOCOUNTON;   -- Insert statements for procedure here       INSERT INTO [dbo].[Customers]([CustName],[CustEmail])       VALUES(@CustName,@CustEmail)       RETURN 1   END   GO   /****** Object:  StoredProcedure [dbo].[Update_Customer]    Script Date: 12/27/2015 1:44:05 PM ******/   SETANSI_NULLSON   GO   SETQUOTED_IDENTIFIERON   GO   -- =============================================   -- Author:      <Author,,Name>   -- Create date: <Create Date,,>   -- Description: <Description,,>   -- =============================================   CREATE PROCEDURE [dbo].[Update_Customer]       -- Add the parameters for the stored procedure here        @Id Bigint       ,@CustNameNvarchar(100)       ,@CustEmailNvarchar(150)   AS   BEGIN       -- SET NOCOUNT ON added to prevent extra result sets from       -- interfering with SELECT statements.       SETNOCOUNTON;   -- Insert statements for procedure here       UPDATE [dbo].[Customers] SET[CustName] = @CustName,[CustEmail]= @CustEmail       WHERE [Id] = @Id       RETURN 1   END   GO

启动 MVC 项目

创建示例应用程序,我们需要 Visual Studio 2012 或更高版本,并且该服务器平台必须支持 .NET 4.5。

步骤 1:

通过 SignalR 类库,实现 ASP.NET MVC 的实时通信

Step 2:

通过 SignalR 类库,实现 ASP.NET MVC 的实时通信

Step 3:

通过 SignalR 类库,实现 ASP.NET MVC 的实时通信

点击 OK,Visual Studio 将会创建一个新的 ASP.NET 工程。

使用通用类库

使用通用功能,我们可以减少代码数量。

namespace WebApplication1.Repository   {       interfaceIRepository < T > : IDisposablewhereT: class       {           IEnumerable < T > ExecuteQuery(stringspQuery, object[] parameters);           TExecuteQuerySingle(stringspQuery, object[] parameters);           intExecuteCommand(stringspQuery, object[] parameters);       }   }

接口 IRepository

显示一个通用类库的 T 型接口,它是 SQL 实体的 LINQ。它提供了一个基本的界面操作,如 Insert, Update, Delete, GetById and GetAll。

IDisposable

IDisposable接口提供了一种机制,释放非托管资源。

where T : class

这是制约泛型参数的一类。点击查看更多。

类型参数必须是引用类型;这也适用于任何类,接口,委托或数组类型。

namespace WebApplication1.Repository   {       public class GenericRepository < T > : IRepository < T > whereT: class       {           Customer_Entities context = null;           privateDbSet < T > entities = null;           public GenericRepository(Customer_Entities context)           {               this.context = context;               entities = context.Set < T > ();           }           ///<summary>           /// Get Data From Database           ///<para>Use it when to retive data through a stored procedure</para>           ///</summary>           public IEnumerable < T > ExecuteQuery(stringspQuery, object[] parameters)           {               using(context = newCustomer_Entities())               {                       returncontext.Database.SqlQuery < T > (spQuery, parameters).ToList();               }           }           ///<summary>           /// Get Single Data From Database           ///<para>Use it when to retive single data through a stored procedure</para>           ///</summary>           public TExecuteQuerySingle(stringspQuery, object[] parameters)           {               using(context = newCustomer_Entities())               {                   returncontext.Database.SqlQuery < T > (spQuery, parameters).FirstOrDefault();               }           }           ///<summary>           /// Insert/Update/Delete Data To Database           ///<para>Use it when to Insert/Update/Delete data through a stored procedure</para>           ///</summary>           public intExecuteCommand(stringspQuery, object[] parameters)           {               int result = 0;               try               {                   using(context = newCustomer_Entities())                   {                       result = context.Database.SqlQuery < int > (spQuery, parameters).FirstOrDefault();                   }               }               catch               {}               return result;           }           private bool disposed = false;           protected virtualvoid Dispose(bool disposing)           {               if (!this.disposed)               {                   if (disposing)                   {                       context.Dispose();                   }               }               this.disposed = true;           }           public void Dispose()           {               Dispose(true);               GC.SuppressFinalize(this);           }       }   }

使用 middle-tire 结构

namespace WebApplication1.Services   {       public partial class CustomerService       {           privateGenericRepository < Customer > CustRepository;           //CustomerRepositoryCustRepository;           public CustomerService()           {               this.CustRepository = newGenericRepository < Customer > (newCustomer_Entities());           }           public IEnumerable < Customer > GetAll(object[] parameters)           {               stringspQuery = "[Get_Customer] {0}";               returnCustRepository.ExecuteQuery(spQuery, parameters);           }           public CustomerGetbyID(object[] parameters)           {               stringspQuery = "[Get_CustomerbyID] {0}";               returnCustRepository.ExecuteQuerySingle(spQuery, parameters);           }           public int Insert(object[] parameters)           {               stringspQuery = "[Set_Customer] {0}, {1}";               returnCustRepository.ExecuteCommand(spQuery, parameters);           }           public int Update(object[] parameters)           {               stringspQuery = "[Update_Customer] {0}, {1}, {2}";               returnCustRepository.ExecuteCommand(spQuery, parameters);           }           public int Delete(object[] parameters)           {               stringspQuery = "[Delete_Customer] {0}";               returnCustRepository.ExecuteCommand(spQuery, parameters);           }       }   }

在 MVC 架构应用程序中使用通用库

namespace WebApplication1.Controllers   {       public class HomeController: Controller       {           private CustomerServiceobjCust;           //CustomerRepositoryCustRepository;           public HomeController()               {                   this.objCust = newCustomerService();               }               // GET: Home           public ActionResult Index()           {               int Count = 10;               object[] parameters = {                   Count               };               var test = objCust.GetAll(parameters);               return View(test);           }           public ActionResult Insert()           {               return View();           }           [HttpPost]           public ActionResult Insert(Customer model)           {               if (ModelState.IsValid)               {                   object[] parameters = {                       model.CustName,                       model.CustEmail                   };                   objCust.Insert(parameters);               }               return RedirectToAction("Index");           }           public ActionResult Delete(int id)           {               object[] parameters = {                   id               };               this.objCust.Delete(parameters);               return RedirectToAction("Index");           }           public ActionResult Update(int id)           {               object[] parameters = {                   id               };               return View(this.objCust.GetbyID(parameters));           }           [HttpPost]           public ActionResult Update(Customer model)           {               object[] parameters = {                   model.Id,                   model.CustName,                   model.CustEmail               };               objCust.Update(parameters);               return RedirectToAction("Index");           }           protected override void Dispose(bool disposing)           {               base.Dispose(disposing);           }       }   }

在 MVC 架构应用程序中使用视图

Index

@model IList   <WebApplication1.Models.Customer>   @{   ViewBag.Title = "Index";   }       <linkhref="~/Content/bootstrap/css/bootstrap.min.css"rel="stylesheet"/>       <divclass="clearfix">        </div>       <divclass="clearfix">        </div>       <divclass="container">           <divclass="table-responsive">   @Html.ActionLink("New Customer", "Insert", "Home")               <tableclass="table table-bordered table-striped">                   <thead>                       <tr>                           <th>ID</th>                           <th>Name</th>                           <th>Email ID</th>                           <th>Delete</th>                           <th>Update</th>                       </tr>                   </thead>                   <tbody>                   @if (Model != null)                   {                       foreach (var item in Model)                       {                          <tr>                              <td>@item.Id</td>                              <td>@item.CustName</td>                              <td>@item.CustEmail</td>                              <td>@Html.ActionLink("Delete", "Delete", "Home", new { id = @item.Id }, null)</td>                              <td>@Html.ActionLink("Update", "Update", "Home", new { id = @item.Id }, null)</td>                          </tr>                       }                   }                   </tbody>               </table>           </div>           <divclass="clearfix">            </div>       </div>

Insert

@model WebApplication1.Models.Customer   @{   ViewBag.Title = "Insert";   }   <link href="~/Content/bootstrap/css/bootstrap.min.css"rel="stylesheet"/>   <div class="clearfix">    </div>   <div class="clearfix">    </div>   <div class="container">       <div class="table-responsive col-md-6 col-md-offset-3">           <table class="table table-bordered table-striped">               <tbody>   @using (Html.BeginForm("Insert", "Home", FormMethod.Post))   {   @*                   <tr>                       <td class="col-md-4">ID</td>                       <td class="col-md-8">@Html.TextBoxFor(m =>m.Id)</td>                   </tr>*@                   <tr>                       <td class="col-md-4">Name                       </td>                       <td class="col-md-8">@Html.TextBoxFor(m =>m.CustName)                       </td>                   </tr>                   <tr>                       <td class="col-md-4">Email ID                       </td>                       <td class="col-md-8">@Html.TextBoxFor(m =>m.CustEmail)                       </td>                   </tr>                   <tr>                       <td class="text-right"colspan="2">                           <input type="submit"value="Save"class="btnbtn-primary"/>                       </td>                   </tr>   }               </tbody>           </table>       </div>       <div class="clearfix">        </div>   @Html.ActionLink("Home", "Index", "Home")   </div>

Update

@model WebApplication1.Models.Customer   @{   ViewBag.Title = "Update";   }   <link href="~/Content/bootstrap/css/bootstrap.min.css"rel="stylesheet"/>   <div class="clearfix">    </div>   <div class="clearfix">    </div>   <div class="container">       <div class="table-responsive">           <table class="table table-bordered table-striped">               <thead>                   <tr>                       <th>Name</th>                       <th>Email ID</th>                       <th>Update</th>                   </tr>               </thead>               <tbody>                   <tr>   @using (Html.BeginForm("Update", "Home", FormMethod.Post))   {                       <td>@Html.TextBoxFor(m =>m.CustName)</td>                       <td>@Html.TextBoxFor(m =>m.CustEmail)</td>                       <td>                           <inputtype="submit"value="Update"class="btnbtn-primary"/>                       </td>   }                   </tr>               </tbody>           </table>       </div>   </div>

步骤2:

启动 SignalR

第一件事是获得 NuGet 参照。

在 NuGet 上获得。

安装 Microsoft.AspNet.SignalR 包 
Microsoft.AspNet.SignalR

注册 SignalR 中间件

安装后需要创建 OwinStartup 类。

下面的代码将一段简单中间件向 OWIN 管道,实现接收 Microsoft.Owin.IOwinContext 实例的功能。

当服务器收到一个 HTTP 请求,OWIN 管道调用中间件。中间件设置内容类型的响应和写响应体。

Startup.cs

using System;   using System.Threading.Tasks;   using Microsoft.Owin;   using Owin;   [assembly: OwinStartup(typeof (WebAppSignalR.Startup))]   namespace WebAppSignalR   {       public class Startup       {           public void Configuration(IAppBuilder app)           {               app.MapSignalR();           }       }   }

创建使用 Hub 类

完成前面的过程之后,创建一个 Hub。一个SignalR Hub 让从服务器到客户端连接,并从客户端到服务器的远程过程调用(RPC)。

CustomerHub.cs

using System;   using System.Collections.Generic;   using System.Linq;   using System.Web;   using Microsoft.AspNet.SignalR;   using Microsoft.AspNet.SignalR.Hubs;   namespace WebApplication1.Hubs   {       public class CustomerHub: Hub       {           [HubMethodName("broadcastData")]           public static void BroadcastData()           {               IHubContext context = GlobalHost.ConnectionManager.GetHubContext < CustomerHub > ();               context.Clients.All.updatedData();           }       }   }

代码说明

IHubContext context = GlobalHost.ConnectionManager.GetHubContext<CustomerHub>();

获得 CustomerHub context:

context.Clients.All.updatedData();

它请求 SignalR 的客户端部分,并告诉它执行 JavaScript 的 updatedData()方法。

修改现有视图 Let’s Modify our Existing View

修改一部分索引视图,将通过局部视图显示数据。

Index

@model IList < WebApplication1.Models.Customer > @   {       ViewBag.Title = "Index";   } < linkhref = "~/Content/bootstrap/css/bootstrap.min.css"   rel = "stylesheet" / > < divclass = "clearfix" > & nbsp; < /div> < divclass = "clearfix" > & nbsp; < /div> < divclass = "container" > < divclass = "table-responsive" > @Html.ActionLink("New Customer", "Insert", "Home") < hr / > < divid = "dataTable" > < /div> < /div> < divclass = "clearfix" > & nbsp; < /div> < /div>   @section JavaScript   { < scriptsrc = "~/Scripts/jquery.signalR-2.2.0.min.js" > < /script> < scriptsrc = "/signalr/hubs" > < /script> < scripttype = "text/javascript" > $(function ()       {           // Reference the hub.           var hubNotif = $.connection.customerHub;           // Start the connection.           $.connection.hub.start().done(function ()           {               getAll();           });           // Notify while anyChanges.           hubNotif.client.updatedData = function ()           {               getAll();           };       });       function getAll()       {           var model = $('#dataTable');           $.ajax(           {               url: '/home/GetAllData',               contentType: 'application/html ; charset:utf-8',               type: 'GET',               dataType: 'html'           }).success(function (result)           {               model.empty().append(result);           }).error(function (e)           {               alert(e);           });       } < /script>   }

局部视图

<table class="table table-bordered table-striped">       <thead>           <tr>               <th>ID</th>               <th>Name</th>               <th>Email ID</th>               <th>Delete</th>               <th>Update</th>           </tr>       </thead>       <tbody> @if (Model != null) { foreach (var item in Model) {           <tr>               <td>@item.Id</td>               <td>@item.CustName</td>               <td>@item.CustEmail</td>               <td>@Html.ActionLink("Delete", "Delete", "Home", new { id = @item.Id }, null)</td>               <td>@Html.ActionLink("Update", "Update", "Home", new { id = @item.Id }, null)</td>           </tr> } } </tbody>       </table>

修改现有 Controller

主 Controller:

在主 Controller,我们将添加一个名为 GetAllDaTa()的方法。这是方法。

[HttpGet]   public ActionResult GetAllData()   {       int Count = 10;       object[] parameters = {           Count       };       var test = objCust.GetAll(parameters);       return PartialView("_DataList", test);   }

在这里,返回局部视图返回的数据列表,且只返回空。

// GET: Home  public ActionResult Index()  {     return View();  }

主 Controller

public class HomeController: Controller   {       private CustomerService objCust;       //CustomerRepositoryCustRepository;       public HomeController()       {           this.objCust = newCustomerService();       }       // GET: Home       public ActionResult Index()       {           return View();       }       [HttpGet]       public ActionResult GetAllData()       {           int Count = 10;           object[] parameters = {               Count           };           var test = objCust.GetAll(parameters);           return PartialView("_DataList", test);       }       public ActionResult Insert()       {           return View();       }       [HttpPost]       public ActionResult Insert(Customer model)       {           if (ModelState.IsValid)           {               object[] parameters = {                   model.CustName,                   model.CustEmail               };               objCust.Insert(parameters);           }           //Notify to all           CustomerHub.BroadcastData();           return RedirectToAction("Index");       }       public ActionResult Delete(int id)       {           object[] parameters = {               id           };           this.objCust.Delete(parameters);           //Notify to all           CustomerHub.BroadcastData();           return RedirectToAction("Index");       }       public ActionResult Update(int id)       {           object[] parameters = {               id           };           return View(this.objCust.GetbyID(parameters));       }       [HttpPost]       public ActionResult Update(Customer model)       {           object[] parameters = {               model.Id,               model.CustName,               model.CustEmail           };           objCust.Update(parameters);           //Notify to all           CustomerHub.BroadcastData();           returnRedirectToAction("Index");       }       protected override void Dispose(bool disposing)       {           base.Dispose(disposing);       }   }

输出

通过 SignalR 类库,实现 ASP.NET MVC 的实时通信

希望能够帮助到您。

OneAPM 助您轻松锁定 .NET 应用性能瓶颈,通过强大的 Trace 记录逐层分析,直至锁定行级问题代码。以用户角度展示系统响应速度,以地域和浏览器维度统计用户使用情况。想阅读更多技术文章,请访问 OneAPM 官方博客。 
本文转自 OneAPM 官方博客

原文地址: http://www.c-sharpcorner.com/UploadFile/302f8f/Asp-Net-mvc-real-time-app-with-signalr/


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI