一切福田,不離方寸,從心而覓,感無不通。

将视图添加到 ASP.NET Core MVC 应用

在本部分中,将修改 HelloWorldController 类,进而使用 Razor 视图文件来顺利封装为客户端生成 HTML 响应的过程。 使用 Razor 创建视图模板文件。 当前,Index 方法返回带有在控制器类中硬编码的消息的字符串。 C#

  上面的代码调用控制器的 View 方法。 添加视图 Visual Studio Visual Studio Code Visual Studio for Mac 右键单击“视图”文件夹,然后单击“添加”>“新文件夹”,并将文件夹命名为“HelloWorld”。 右键单击“Views/HelloWorld”文件夹,然后单击“添加”>“新项”。 在“添加新项 – MvcMovie”对话框中 在右上角的搜索框中,输入“视图” 选择“Razor 视图” 保持“名称”框的值:Index.cshtml 。 选择“添加” 为 HelloWorldController 添加 Index 视图。 添加一个名为“Views/HelloWorld”的新文件夹。 向 Views/HelloWorld 文件夹添加名为“Index.cshtml”的新文件。 右键单击“视图”文件夹,然后单击“添加”>“新文件夹”,并将文件夹命名为“HelloWorld”。 右键单击“Views/HelloWorld”文件夹,然后单击“添加”>“新文件” 。 在“新建文件”对话框中 : 在左窗格中,选择“Web” 。 在中间窗格中,选择“空 HTML 文件” 。 在“名称”框中键入“Index.cshtml” 。 选择“新建” 。 使用以下内容替换 Razor 视图文件 Views/HelloWorld/Index.cshtml 的内容 : HTML

  导航到 https://localhost:{PORT}/HelloWorld。 更改视图和布局页面 选择菜单链接(“MvcMovie”、“首页”和“隐私”) 。 布局模板使你能够在一个位置指定网站的 HTML 容器布局,然后将它应用到网站中的多个页面。 更改布局文件中的标题、页脚和菜单链接 在标题和页脚元素中,将 MvcMovie 更改为 Movie App。 将定位点元素 <a […]

龙生   20 Sep 2019
View Details

TagHelper是怎么实现的

众所周知,在asp.net core中编写Razor视图的时候,用了一种新的写法--TagHelper 那这个TagHelper是怎么回事呢?   首先来看看TagHelper的项目位置,它是位于Microsoft.AspNetCore.Mvc.TagHelpers。 如果看到project.json,可以发现,它还依赖一个比较重要的东西Microsoft.AspNetCore.Mvc.Razor 为什么这么说呢,其实很简单,看了里面诸多TagHelper,就会发现,里面都是继承了 Microsoft.AspNetCore.Razor.TagHelpers下面的TagHelper这个抽象类。 下面就以我们天天用到的表单--FormTagHelper为例来说一下,他是怎么实现的。 首先要看看TagHelper这个抽象类:

里面包含两比较重要的方法:Process和ProcessAsync 其实看方法名就应该知道一个是同步的方法一个是异步的方法 因为这个是输出html的方法,你说,这能不重要吗?下面来看看FormTagHelper的具体实现吧!

先来看看HtmlTargetElement这个Attribute是用来干嘛的 简单来说,它指定了我们html标签(<form></form>)以及一些相关的元素。 可以看到,诸多Attributes = XXXAttributeName,其中的XXXAttributeName是在类里面定义的变量。

  再来看看下面的图,相对比一看,是不是就很清晰了呢? 我们可以看到下面的好几个属性,如Controller,它的上面是有 HtmlAttributeName来标注的 而且这个指向的名字还是ControllerAttributeName(也就是asp-controller)。这个就是用来接收asp-controller的值。

相对来说,这样做只是起了个别名。

  当然,我们也是可以不指定别名的,也可以不用在HtmlTargetElement指明Attributes 好比如下的代码,就可以直接用Controller

  还有一个RouteValues的属性,它是一个键值对,用来存放参数的,具体可以怎么用呢? 总的来说有两种用法。可以看到它指向asp-all-route-data和asp-route-

用法如下:一种是用asp-all-route-data来接收一个IDictionary类型的变量,一种是通过asp-route-*的方式来接收参数*的值。 这两种写法是等价的。 下面就是FormTagHelper的构造函数和一个Generator属性

  由于在Core中,依赖注入随处可见,看到这个写法马上就是想到了这个 果不其然,发现其对应了一个实现类:DefaultHtmlGenerator。

  这个类里面,我们看到了熟悉的TagBuilder,就算不去看它里面的实现都能知道它是用来干嘛的 它就是用来创建我们的Html标签,相信用过MVC的,多多少少都扩展过HtmlHelper,这是类似的。 最后,也是最最重要的重写的Process方法。 可以看到开始就判断了表单<form>中是否包含了action这个属性output.Attributes.ContainsName(HtmlActionAttributeName) 如果包含,就是正常的html标签。换句话说,正常的html写法和我们的TagHelper方法会有冲突,只能用其中一种。 当我们这样写的时候,编译能通过。 但是,运行的时候就会出错。 再下面的处理就是用了TagBuilder去处理了。 收集路由的数据放到一个字典中->区域是否存在->用Generator去创建form表单,返回TagBuilder对象->TagHelperOutput对象把tagbuilder的innerhtml等信息输出。 如下面的写法:

生成对应的html如下:

到这里,FormTagHelper的讲解就算是OK,至于其他的,原理都是差不多,就不再累赘了。 来看看,到底有多少种TagHelper(还没有部分没有列出来),以及它们包含的属性。 下面是我们自己写一个TagHelper——CatcherATagHelper,这个TagHelper是干什么的呢?它只是一个精简版的A标签。

   这里提供了两种写法供大家参考 一种是借助IUrlHelperFactory去生成链接 一种是借助IHtmlGenerator去生成链接 写好了之后要怎么用呢? 不知道大家有没有留意_ViewImports.cshtml这个文件

这个是默认情况下帮我们添加的TagHelper 我们可以在要用到那个TagHelper的地方添加就好  Index.cshtml   addTagHelper的用法如下: @addTagHelper 你的TagHelper , 你的TagHelper所在的命名空间 或者更直接 @addTagHelper * , 你的TagHelper所在的命名空间   可以添加,当然也可以删除,删除是@removeTagHelper 当我们在自己的框架中完全重写了一套自己的TagHelper,那么这个时候,微软自己的TagHelper我们就可以通过下面的方法来移除了。 @removeTagHelper […]

龙生   19 Sep 2019
View Details

.NET Core开源API网关 – Ocelot中文文档

Ocelot是一个用.NET Core实现并且开源的API网关,它功能强大,包括了:路由、请求聚合、服务发现、认证、鉴权、限流熔断、并内置了负载均衡器与Service Fabric、Butterfly Tracing集成。这些功能只都只需要简单的配置即可完成,下面我们会对这些功能的配置一一进行说明。 介绍 简单的来说Ocelot是一堆的asp.net core middleware组成的一个管道。当它拿到请求之后会用一个request builder来构造一个HttpRequestMessage发到下游的真实服务器,等下游的服务返回response之后再由一个middleware将它返回的HttpResponseMessage映射到HttpResponse上。 API网关—— 它是系统的暴露在外部的一个访问入口。这个有点像代理访问的家伙,就像一个公司的门卫承担着寻址、限制进入、安全检查、位置引导、等等功能。 Ocelot的基本使用 用一台web service来host Ocelot,在这里有一个json配置文件,里面设置了所有对当前这个网关的配置。它会接收所有的客户端请求,并路由到对应的下游服务器进行处理,再将请求结果返回。而这个上下游请求的对应关系也被称之为路由。 集成Identity Server 当我们涉及到认证和鉴权的时候,我们可以跟Identity Server进行结合。当网关需要请求认证信息的时候会与Identity Server服务器进行交互来完成。 网关集群 只有一个网关是很危险的,也就是我们通常所讲的单点,只要它挂了,所有的服务全挂。这显然无法达到高可用,所以我们也可以部署多台网关。当然这个时候在多台网关前,你还需要一台负载均衡器。 Consul 服务发现 在Ocelot已经支持简单的负载功能,也就是当下游服务存在多个结点的时候,Ocelot能够承担起负载均衡的作用。但是它不提供健康检查,服务的注册也只能通过手动在配置文件里面添加完成。这不够灵活并且在一定程度下会有风险。这个时候我们就可以用Consul来做服务发现,它能与Ocelot完美结合。 集成网关 在asp.net core 2.0里通过nuget即可完成集成,或者命令行dotnet add package Ocelot以及通过vs2017 UI添加Ocelot nuget引用都可以。

  配置 我们需要添加一个.json的文件用来添加Ocelot的配置,以下是最基本的配置信息。

  要特别注意一下BaseUrl是我们外部暴露的Url,比如我们的Ocelot运行在http://123.111.1.1的一个地址上,但是前面有一个 nginx绑定了域名http://api.jessetalk.cn,那这里我们的BaseUrl就是 http://api.jessetalk.cn。 将配置文件加入ASP.NET Core Configuration 我们需要通过WebHostBuilder将我们添加的json文件添加进asp.net core的配置

    配置依赖注入与中间件 在startup.cs中我们首先需要引用两个命名空间

  接下来就是添加依赖注入和中间件

 

  Ocelot功能介绍 通过配置文件可以完成对Ocelot的功能配置:路由、服务聚合、服务发现、认证、鉴权、限流、熔断、缓存、Header头传递等。在配置文件中包含两个根节点:ReRoutes和GlobalConfiguration。ReRoutes是一个数组,其中的每一个元素代表了一个路由,我们可以针对每一个路由进行以上功能配置。下面是一个完整的路由配置

  Downstream是下游服务配置 UpStream是上游服务配置 Aggregates 服务聚合配置 ServiceName, LoadBalancer, UseServiceDiscovery 配置服务发现 AuthenticationOptions 配置服务认证 RouteClaimsRequirement 配置Claims鉴权 RateLimitOptions为限流配置 FileCacheOptions 缓存配置 QosOptions 服务质量与熔断 DownstreamHeaderTransform头信息转发 我们接下来将对这些功能一一进行介绍和配置 路由 路由是API网关最基本也是最核心的功能、ReRoutes下就是由多个路由节点组成。

  而每一个路由由以下几个基本信息组成: 下面这个配置信息就是将用户的请求 /post/1 转发到 localhost/api/post/1

  DownstreamPathTemplate:下游戏 DownstreamScheme:下游服务http schema DownstreamHostAndPorts:下游服务的地址,如果使用LoadBalancer的话这里可以填多项 UpstreamPathTemplate: 上游也就是用户输入的请求Url模板 […]

龙生   05 Sep 2019
View Details

Dapper ORM VS SqlSugar ORM的 8场对决

比赛规则
1.统一使用Realse版本的最新 DLL,Realse模式启用程序

2.为了平衡CPU和数据库空闲情况,使用车轮战,每场比赛连续10回合比试

3.多次重启电脑取平均成绩上图

比赛成员
1.SqlSugar 3.1.01

2.Dapper 1.5.0.2 Dapper.Contrib 1.5 官方DLL

龙生   05 Sep 2019
View Details

pdf.js使用方法

项目中 显示 pdf 的功能,浏览过不少的技术帖,都不太理想,花了点时间研究了下pdf.js正确使用方法,总结下:1.防止自己忘记 2.工作留有痕迹 3.供大家参考借鉴

上面是最开始探索 pdf.js 使用的方法 时 的猜想 其实 pdf.js 真正使用方法非常简单 (一行代码就可以搞定) pdf.js使用步骤 一. 到官网下载 pdf.js 插件并解压  (地址: http://mozilla.github.io/pdf.js/ ) 1: 进入官网  2 : 选择稳定版 下载 3: 下载至本地 4 : 解压 5:创建PDF.js文件夹 并将刚解压的文件放入其中 二.将 PDF.js 文件夹 放到 项目服务器根目录下 小伙伴 可能会有点头晕 先跟着做 稍后解释 1.登录 项目服务器 2.登录 服务器 后将 PDF.js 文件夹 拷贝 到 项目 服务器 的根目录 三. 使用 pdf.js 显示 pdf 文件 1.打开浏览器 新建一个 标签页 输入 你的项目服务器 地址 这里我用我的服务器 地址进行演示 10.0.0.5 2.当 你访问 项目 服务器 根目录(10.0.0.5) 能够 看到 PDF.js 这个文件夹 说明 这一步已经完成了 3.在PDF.js 中 依次打开 web 文件夹 viewer.html 文件 (PDF.js/web/viewer.html) 4.随后会显示 截图上的 […]

龙生   04 Sep 2019
View Details

在线查看PDF文件,pdf.js使用方法

PDF.js可以实现在html下直接浏览pdf文档,是一款开源的pdf文档读取解析插件,非常强大,能将PDF文件渲染成Canvas。PDF.js主要包含两个库文件,一个pdf.js和一个pdf.worker.js,一个负责API解析,一个负责核心解析。 首先引入pdf.js文件<script type="text/javascript" src=’pdf.js'></script> PDF.js大部分用法都是基于Promise的,PDFJS.getDocument(url)方法返回的就是一个Promise:

PDF的解析工作需要通过pdf.getPage(page)去执行,这个方法返回的也是一个Promise,因此可以去逐页解析PDF:

官网地址:http://mozilla.github.io/pdf.js/ 渲染页面 各PDF页面有它自己的视窗,它定义了像素大小(n.72dpi和初始旋转。默认情况下,该窗口将缩放到PDF但是通过修改视图可以更改此操作。当创建了视图时,还会创建一个初始转换矩阵,它考虑到期望的规模、旋转,并转换坐标系统(0点)PDF文档底部左边,而画布0是 左。

官方给出的示例:

  另外较大的PDF文件可以用base 64编码方式加载,例如:

  pdf翻页处理:

    关于page方式的使用: 解析结果,我们可以看下这个对象提供的方法: 方法 返回 getAnnotations A promise that is resolved with an {Array} of the annotation objects. getTextContent That is resolved a TextContent object that represent the page text content. getViewport Contains ‘width’ and ‘height’ properties along with transforms required for rendering. render An object that contains the promise, which is resolved when the page finishes rendering. 我们可以试试调用getTextContent方法,并将其结果打印出来:

输入格式大致如下:

PDF.js能将每页文本的字符串、位置、字体都解析出来。 官网用的viewer.js:http://mozilla.github.io/pdf.js/web/viewer.html,首先底图是一个Canvas,内容和PDF一样(通过下面介绍的page.render方法可以得到),底图之上是一个textLayer,这一层就是通过page.getTextContent()得到了字体的位置和样式,再覆盖在Canvas上。 […]

龙生   04 Sep 2019
View Details

Asp .Net Core 2.0 登录授权以及多用户登录

用户登录是一个非常常见的应用场景 .net core 2.0 的登录方式发生了点变化,应该是属于是良性的变化,变得更方便,更容易扩展。 配置 打开项目中的Startup.cs文件,找到ConfigureServices方法,我们通常在这个方法里面做依赖注入的相关配置。添加如下代码:

这段代码的大概意思就是,添加授权支持,并添加使用Cookie的方式,配置登录页面和没有权限时的跳转页面。 再找到Configure方法,添加 app.UseAuthentication(),使用授权:

这样基本的配置就完成了。 登录 添加一个Controller,如AccountController,再添加一个Action,如 Login,所配置的路由,要与上面的配置对应,不然跳转登录时会跳错页面。 用户提交用户名和密码,登录代码大致如下:

这里要注意的是 AuthenticationType 所设置的Scheme一定要与前面的配置一样,这样对应的登录授权才会生效。 使用登录身份 登录的目录,就是希望有些页面或者资源只有登录以后才可访问。使用AuthorizeAttribute来做限制。在需要做限制的Controller上加上[Authorize]特性来做限制。

这样这个Controller下的所有的Action都必需要登录后才可访问。如果希望其中某些Action可以不用登录也可访问,可以添加例外:

到这里一个最基础的登录就完成了。 在Web项目中,通常会遇到一个问题,后端管理员和前台用户。这两个用户都是可登录的,在 .net core 2.0,这个将很容易实现。 多用户登录 添加一个登录方案(Scheme) CookieAuthenticationDefaults.AuthenticationScheme,这是系统已经定义好的一个默认的登录方案,添加一个新的来实现一个不同的身份登录。代码如下:

添加使用这个新的方案,在Startup.cs文件下:

添加新的登录方案,并配置一个新的登录页面,登录的方法和刚才是一样,只是AuthenticationType使用了新的方案。

验证登录状态 使用方法和之前的差不多,换成新的CustomerAuthorizeAttribute就行了:

CustomerAuthorizeAttribute这个类,不是必需的,只是为了方便使用而写,其实完全可以只定义一个新的方案(Scheme)就行了。 谁才是HttpContext.User? 登录了多个用户,那么谁才是HttpContext.User呢?如果你的Controller或者Action上有使用AuthorizeAttribute,那这个Attribute使用的登录方案是哪个,则这个HttpContext.User对应的就是那个方案的登录用户。如果没有使用,则AddAuthentication()方法默认指它的方案(Scheme)所登录的用户,就是这个HttpContext.User了。 如何获取对应方案的登录用户呢?使用HttpContext.AuthenticateAsync

退出登录 这个就简单了,指定方案退出就可以了。

from:http://www.zkea.net/codesnippet/detail/asp-net-core-multi-login-user.html

龙生   02 Sep 2019
View Details

ASP.NET CORE中使用Cookie身份认证

大家在使用ASP.NET的时候一定都用过FormsAuthentication做登录用户的身份认证,FormsAuthentication的核心就是Cookie,ASP.NET会将用户名存储在Cookie中。 现在到了ASP.NET CORE的时代,但是ASP.NET CORE中没有FormsAuthentication这个东西,那么怎么做身份认证呢?答案是ASP.NET CORE已经为我们内置了Cookie身份认证的功能,而且使用起来非常方便,注意本文是基于ASP.NET CORE 2.0版本来阐述Cookie认证方式的。   1.从ASP.NET CORE OWIN框架中启用Cookie身份认证功能 要在ASP.NET CORE中使用Cookie身份认证,第一步就是在项目中的OWIN框架文件Startup.cs中启用Cookie身份认证中间件。 首先我们在Startup中的ConfigureServices方法中使用services.AddAuthentication注册Cookie认证服务,如下代码所示:

然后在Startup中的Configure方法中使用app.UseAuthentication启用Cookie认证中间件(注意其中app.UseAuthentication和app.UseMvc的调用顺序不能反),如下代码所示:

这里顺便说一下app.UseAuthentication是用来干什么的,app.UseAuthentication会启用Authentication中间件,该中间件会根据当前Http请求中的Cookie信息来设置HttpContext.User属性(后面会用到),所以只有在app.UseAuthentication方法之后注册的中间件才能够从HttpContext.User中读取到值,这也是为什么上面强调app.UseAuthentication方法一定要放在下面的app.UseMvc方法前面,因为只有这样ASP.NET Core的MVC中间件中才能读取到HttpContext.User的值。     2.登录用户 在ASP.NET CORE中使用Cookie认证登录用户的方法和传统的FormsAuthentication不太一样,大致步骤如下: 创建Claim类型的数组,将登录用户的所有信息(比如用户名)存储在Claim类型的字符串键值对中 将上面创建的Claim类型的数组传入ClaimsIdentity中,用来构造一个ClaimsIdentity对象 将上面创建的ClaimsIdentity对象传入ClaimsPrincipal中,用来构造一个ClaimsPrincipal对象 调用HttpContext.SignInAsync方法,传入上面创建的ClaimsPrincipal对象,完成用户登录 所以我们可以看到整个ASP.NET CORE的Cookie认证登录流程比以前ASP.NET的FormsAuthentication还是要复杂许多,毕竟以前一个FormsAuthentication.SetAuthCookie方法就搞定了。   在本文的例子中我们在项目中默认的HomeController中创建了一个Acion方法Login,来实现用户登录的代码。当然这里我们实现的是最简的Cookie登录,下面代码中实际上还可以设置Cookie是否持久化、Cookie多久过期、存储登录用户信息的Cookie的名字是什么等,我们就不做过多介绍了,大家可以阅读本文最后推荐的两份官方文档了解更多。 Login方法的代码如下:

  如果当前Http请求本来登录了用户A,现在调用HttpContext.SignInAsync方法登录用户B,那么相当于注销用户A,登录用户B     3.读取登录用户信息 那么用户登录后怎么将登录用户的信息(比如用户名)读取出来呢?我们在HomeController的Index方法中演示了如何判断当前用户是否已经登录,并且读出登录用户的用户名,Index方法的代码如下所示:

注意,最好还是用HttpContext.User.Identity.IsAuthenticated来判断用户是否已经登录     4.注销用户 那么登录用户后怎么注销登录呢?我们在HomeController的Logout方法中演示了如何注销登录的用户,代码如下所示:

如果当前Http请求本来就没有登录用户,那么调用HttpContext.SignOutAsync方法时也不会报错     5.负载均衡   警告: ASP.NET Core使用 ASP.NET Core data protection stack 来实现Cookie身份认证。如果在服务器集群中必须配置 ASP.NET Core Data Protection,有关详细信息,请参阅 Configuring data protection。如果你的ASP.NET Core站点使用了负载均衡部署了多个实例,就要做ASP.NET Core Data Protection的配置,否则ASP.NET CORE跨多个实例进行Cookie身份认证会失败。 还可以参考:Host ASP.NET Core in a web farm 以及 Share authentication cookies among ASP.NET apps 如何管理ASP.NET Core Data Protection的过期key,可以查看:Data Protection – […]

龙生   02 Sep 2019
View Details