中间件中渲染Razor视图

前言

上一篇文章《ASP.NET Core 奇技淫巧(1):中间件实现服务端静态化缓存》中介绍了中间件的使用方法、以及使用中间件实现服务端静态化缓存的功能。本系列文章取名“奇技淫巧”不是没道理的,因为这写技巧都是我最近在做的公司实际项目中的一些奇怪的需求之后总结而来的……

要解决的问题

好了,本篇说说如何在中间件中渲染Razor视图。之所以会有这个技巧,是因为我们有个需求:

需要在所有返回404状态的路由都输出一个特定视图。
比如当有id=1的文章,而没有id=2的文章时,那么/url/1.html展示文章详情页,/url/2.html展示404视图。

所以,要实现这个需求只有两种办法:

  1. 当文章查找不到时直接执行return View("404")返回404视图。

  2. 在中间件中执行完MVC的处理之后检查返回状态,如果是错误状态就直接渲染视图并输出。

由于CMS系统中不止一处需要返回404状态,所以因为用代码整洁作为懒惰的借口,决定尝试第二个方法。

实现

实现方式很简单,就是在Configure中注入ICompositeViewEngine实例,构造视图上下文,再渲染视图为字符串,最后输出。其它的分析就在代码注释中说明吧

直接上代码:

  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ICompositeViewEngine engine)

  2. {

  3.    app.Use(async (context, next) =>

  4.    {

  5.        //因为只是在请求最后处理,所以这里直接就运行下一个中间件

  6.        await next();

  7.        //返回后检查是否出现错误的状态

  8.        if (context.Response.StatusCode >= 400)

  9.        {

  10.            context.Response.StatusCode = (int)HttpStatusCode.NotFound;

  11.            //ContentType设置为text/html,使浏览器以正常页面的格式显示

  12.            context.Response.ContentType = "text/html";

  13.            //指向特定的视图

  14.            var viewResult = engine.GetView("~/", "~/Views/Default/Home/Error.cshtml", true);

  15.            if (!viewResult.Success)

  16.                await context.Response.WriteAsync("OMG! 连错误视图都找不到了。。");

  17.            //创建临时的StringWriter实例,用来配置到视图上下文中

  18.            using (var output = new StringWriter())

  19.            {

  20.                //视图上下文对于视图渲染来说很重要,视图中的前后台交互都需要它

  21.                var viewContext = new ViewContext()

  22.                {

  23.                    HttpContext = context,

  24.                    Writer = output,

  25.                    RouteData = new Microsoft.AspNetCore.Routing.RouteData()

  26.                    {

  27.                        //RouteData在这里传入视图,这样视图可以显示错误信息之类的数据

  28.                    },

  29.                    View = viewResult.View,

  30.                    FormContext = new FormContext(),

  31.                    ActionDescriptor = new Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor()

  32.                };

  33.                //渲染

  34.                await viewResult.View.RenderAsync(viewContext);

  35.                //输出到响应体

  36.                await context.Response.WriteAsync(output.ToString());

  37.            }

  38.        }

  39.    });

  40.    //后面是Mvc的中间件,执行Mvc的处理

  41.    //...app.UseMvc

  42. }

总结

这个技巧还能用于单页面应用程序的路由重定向,把所有路由都输出入口页面代码。

相关文章:

  • ASP.NET Core缓存静态资源

  • 中间件实现服务端静态化缓存


原文:https://yangshunjie.com/A-Middleware-Implement-For-Rendering-Razor-Views-In-AspNetCore.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/322796.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决idea启动项目报错:Unable to open debugger port(127.0.0.1:60157):java.net.SocketExceptionsocket closed

转载自 解决idea启动项目报错:Unable to open debugger port(127.0.0.1:60157):java.net.SocketException"socket closed 1.问题描述: 工作当中免不了要重启服务,debug模式下偶尔启动项目,却启动失败报错: Unable to open debugger port (127.0.0.1:60157): java.net.S…

python3如何连接mysql数据库

原本连接数据库用的是mysql_python,但发现无论怎么安装都装不上去,pip和手动安装都失败了 后来才知道用pymysql才是3版本以后最好适用的 命令 pip3 install PyMySQL连接数据库 import pymysql conn pymysql.connect(localhost, root, 123456)

亿些模板【数据结构】

文章目录前言数据结构模板并查集带权并查集堆hash表RMQ线段树树状数组树状数组区间修改版分块主席树有旋TreapSplay替罪羊树文艺平衡树-Splay点分治树链剖分可持久化并查集LCT左偏树前言 因为老是懒得打模板的时候老是扣不到自己的标(因为之前的都打得太丑了),所以…

下一个计划 : .NET/.NET Core应用性能管理

前言 最近几个月一直在研究开源的APM和监控方案,并对比使用了Zipkin,CAT,Sky-walking,PinPoint(仅对比,未实际部署),Elastic APM,TICK Stack,Prometheus等开源产品,其中不乏功能强大的监控和追踪系统,但它们都对.NET/.NET Core没有支持或支持…

详解proxy_pass、upstream与resolver

转载自 详解proxy_pass、upstream与resolver 应用场景 这里列举几个应用场景,下文会针对这几个场景并结合代码进行分析。 (1)proxy_pass upstream upstream foo.example.com {server 127.0.0.1:8001;}server {listen 80;server_na…

如何用python将srt文件转化成数组形式

原srt文件 0 00:00:00,150 --> 00:00:11,430 Fighting this pandemic needs political commitment and commitment at the highest level possible and the Presidents commitment.1 00:00:11,431 --> 00:00:16,020 you have what it is in it and the would it have se…

架构演化:云原生时代开启之系列一演化篇

信息技术从出现伊始到渐成主流,其趋势经历了软件、开源和云三个阶段: 软件改变世界。纵观人类社会漫长的发展历程,农耕时代、工业时代与信息时代可谓是三个明显分水岭,每个时代人类涉及的领域范畴均喷井式增长。作为信息时代最重要…

mysql出现unblock with 'mysqladmin flush-hosts'

转载自 mysql出现unblock with mysqladmin flush-hosts 朋友发来消息,说一个系统应用登录的时候提示连接超时,让帮忙处理一下。 问他应用和数据库是否都正常,回复说数据库好像没有问题,但是应用日志报无法连接数据库。 数据库版…

laravel部署到服务器显示Permission denied

解决这个问题可以先cd到项目根目录中 依次输入以下两个命令 find storage -type d -exec chmod 777 {} \;find storage -type f -exec chmod 777 {} \;不报错就证明成功了

亿些模板【数论数学】

文章目录前言数论数学模板GCDexgcd快速幂线性推逆元线性推逆元(非连续)逆元求组合数矩阵乘法线性筛素数-埃氏筛线性筛素数-线性筛线性筛欧拉-埃氏筛线性求欧拉龟速乘FFTNTT分治FFT多项式求逆扩展中国剩余定理Lucas定理高斯消元BSGS拉格朗日插值二次剩余线性基杜教筛前言 因为老…

基于OIDC(OpenID Connect)的SSO

在[认证授权]系列博客中,分别对OAuth2和OIDC在理论概念方面进行了解释说明,其间虽然我有写过一个完整的示例(https://github.com/linianhui/oidc.example),但是却没有在实践方面做出过解释。在这里新开一个系列博客&am…

Consul集群搭建

转载自 Consul集群搭建 概述 作为服务发现的几种产品,比较可以查看这里。Consul官方也提供了几种产品之间的比较,点击查看。 服务发现产品 Consul有很多组件,但总体来说,它是一个发现和配置服务工具,特性&#xff…

js遍历对象的key和value

如果想要得到数组的键值对,可以用以下方法 object {"name":"kejin","age":"18"}for(var index in object){console.log(index);console.log(object[index]); }

亿些模板【字符串+其他】

文章目录前言其他快读快输卡常DataMakerDataMakerDataMaker字符串模板KMP字符串hashTrie最小表示法ManacherAC自动机SASAM广义SAMPAM其他模板凸包模拟退火前言 因为老是懒得打模板的时候老是扣不到自己的标(因为之前的都打得太丑了),所以导致我十分的不爽。便打算开…

使用Identity Server 4建立Authorization Server (6) - js(angular5) 客户端

预备知识: 学习Identity Server 4的预备知识 第一部分: 使用Identity Server 4建立Authorization Server (1) 第二部分: 使用Identity Server 4建立Authorization Server (2) 第三部分: 使用Identity Server 4建立Authorization Server (3) 第四部分: 使用Identity Server 4建立…

SpringBoot整合kafka(实现producer和consumer)

转载自 SpringBoot整合kafka(实现producer和consumer) 在Windows环境下安装运行Kafka&#xff1a;https://www.jianshu.com/p/d64798e81f3b 本文代码使用的是Spring Boot 2.1.1.RELEASE 版本 <parent><groupId>org.springframework.boot</groupId><art…

js的字符串和变量拼接

使用反引号拼接字符串和变量 let count 1 name 用户${count} console.log(name);注意是反引号不是引号&#xff0c;反引号是Esc下面的一个按键

ASP.NET Core 认证与授权[7]:动态授权

基于资源的授权 有些场景下&#xff0c;授权需要依赖于要访问的资源&#xff0c;例如&#xff1a;每个资源通常会有一个创建者属性&#xff0c;我们只允许该资源的创建者才可以对其进行编辑&#xff0c;删除等操作&#xff0c;这就无法通过[Authorize]特性来指定授权了。因为授…

maven中scope属性的

转载自 maven中scope属性的 Dependency Scope 在POM 4中&#xff0c;<dependency>中还引入了<scope>&#xff0c;它主要管理依赖的部署。目前<scope>可以使用5个值&#xff1a; * compile&#xff0c;缺省值&#xff0c;适用于所有阶段&#xff0c;会随着…

P3384-[模板]树链剖分

正题 题目大意 要求支持路径加和求和&#xff0c;子树加和求和 解题思路 树剖不解释 codecodecode #include<cstdio> #include<algorithm> using namespace std; const int N200000; int tot,cnt,n,m,s,p,ls[N],pw[N],id[N]; int siz[N],dep[N],f[N],son[N],seg…