博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
通过 SignalR 类库,实现 ASP.NET MVC 的实时通信
阅读量:6758 次
发布时间:2019-06-26

本文共 18289 字,大约阅读时间需要 60 分钟。

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

本主题有以下两个步骤:

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

  2. 我们将使用 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:      
-- Create date:
-- 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:
-- Create date:
-- 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:
-- Create date:
-- 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:
-- Create date:
-- 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:
-- Create date:
-- 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:

Getting Started with MVC

Step 2:

Web application

Step 3:

select template

点击 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 > ();          }          ///          /// Get Data From Database          ///
Use it when to retive data through a stored procedure
///
public IEnumerable < T > ExecuteQuery(stringspQuery, object[] parameters) { using(context = newCustomer_Entities()) { returncontext.Database.SqlQuery < T > (spQuery, parameters).ToList(); } } /// /// Get Single Data From Database ///
Use it when to retive single data through a stored procedure
///
public TExecuteQuerySingle(stringspQuery, object[] parameters) { using(context = newCustomer_Entities()) { returncontext.Database.SqlQuery < T > (spQuery, parameters).FirstOrDefault(); } } /// /// Insert/Update/Delete Data To Database ///
Use it when to Insert/Update/Delete data through a stored procedure
///
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  
@{ ViewBag.Title = "Index"; }
@Html.ActionLink("New Customer", "Insert", "Home")
ID Name Email ID Delete Update @if (Model != null) { foreach (var item in Model) { @item.Id @item.CustName @item.CustEmail @Html.ActionLink("Delete", "Delete", "Home", new { id = @item.Id }, null) @Html.ActionLink("Update", "Update", "Home", new { id = @item.Id }, null) } }

Insert

@model WebApplication1.Models.Customer  @{  ViewBag.Title = "Insert";  }    
@using (Html.BeginForm("Insert", "Home", FormMethod.Post)) { @*
*@
}
ID @Html.TextBoxFor(m =>m.Id)
Name @Html.TextBoxFor(m =>m.CustName)
Email ID @Html.TextBoxFor(m =>m.CustEmail)
@Html.ActionLink("Home", "Index", "Home")

Update

@model WebApplication1.Models.Customer  @{  ViewBag.Title = "Update";  }      
@using (Html.BeginForm("Update", "Home", FormMethod.Post)) {
}
Name Email ID Update
@Html.TextBoxFor(m =>m.CustName) @Html.TextBoxFor(m =>m.CustEmail)

步骤2:

启动 SignalR

第一件事是获得 NuGet 参照。

在 NuGet 上获得。

安装 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 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>  }

局部视图

@if (Model != null) { foreach (var item in Model) {
} }
ID Name Email ID Delete Update
@item.Id @item.CustName @item.CustEmail @Html.ActionLink("Delete", "Delete", "Home", new { id = @item.Id }, null) @Html.ActionLink("Update", "Update", "Home", new { id = @item.Id }, null)

修改现有 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);      }  }

输出

output

希望能够帮助到您。

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

本文转自

原文地址:

转载地址:http://byzeo.baihongyu.com/

你可能感兴趣的文章
人事面试100问题--巧妙应答
查看>>
【工具类】怎么进入阿里云docker仓库
查看>>
Ceres-Solver库入门
查看>>
悲惨而又丢人的创业经历:草根创业者含恨倾诉为什么失败
查看>>
理解WebKit和Chromium: WebKit, WebKit2, Chromium和Chrome介绍
查看>>
hanoi塔的递归算法
查看>>
C# 校验给定的ip地址是否合法
查看>>
lumen 登陆 注册 demo
查看>>
基于服务的并行系统的通讯方式探讨
查看>>
设计模式——观察者模式
查看>>
Python多线程 简明例子
查看>>
《地球上的星星》
查看>>
mysql数据库的主从同步,实现读写分离
查看>>
89 fcanf和fprintf
查看>>
javascript——自定义右键菜单
查看>>
求二叉树中相差最大的两个节点间的差值绝对值
查看>>
PHP 类名::class含义
查看>>
设计模式简介和分类,重点在总结
查看>>
数据库默认端口
查看>>
前端框架的区别,优缺点。
查看>>