中间件中渲染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…

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

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

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

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

laravel部署到服务器显示Permission denied

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

基于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]); }

使用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…

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

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

H5的Websocket基本使用

前端代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head> &…

springboot手动提交kafka offset

转载自 springboot手动提交kafka offset enable.auto.commit参数设置成了false 但是测试发现enable.auto.commit参数设置成了false&#xff0c;kafka的offset依然提交了&#xff08;也没有进行人工提交offset&#xff09;。 查看源码 如果我们enable.auto.commit设置为false…

可观测性与原生云监控

在近日发表的一篇文章中&#xff0c;Cindy Sridharan概括介绍了可观测性及其与原生云应用程序监控的关系。可观测性是一种理念&#xff0c;包括监控、日志聚合、指标和分布式跟踪&#xff0c;可以实时更深入地观察系统。 Sridharan的文章基于她就同一个主题所做的Velocity演讲。…

使用Microsoft.AspNetCore.TestHost进行完整的功能测试

简介 Microsoft.AspNetCore.TestHost是可以用于Asp.net Core 的功能测试工具。很多时候我们一个接口写好了&#xff0c;单元测试什么的也都ok了&#xff0c;需要完整调试一下&#xff0c;检查下单元测试未覆盖到的代码是否有bug。步骤为如下&#xff1a;程序打个断点->F5运行…

MockJs案例

有时候前端写好模板后&#xff0c;后端还完工&#xff0c;那么总不能一直让项目停滞吧&#xff0c;这里就用Mockjs来模拟后端接口的数据&#xff0c;让我们先人一步完成项目。 首先创建一个html&#xff0c;导入axios和mockjs 再用mock去拦截请求&#xff0c;如果后端接口写好了…

Entity Framework Core 使用HiLo生成主键

HiLo是在NHibernate中生成主键的一种方式&#xff0c;不过现在我们可以在Entity Framework Core中使用。所以在这篇内容中&#xff0c;我将向您在介绍如何在Entity Framework Core中使用HiLo生成主键。 什么是Hilo&#xff1f; HiLo是High Low的简写&#xff0c;翻译成中文叫高…

Echarts报错:Component series.lines not exists. Load it first.

前几天用的echarts标签是bootcdn的 <script src"https://cdn.bootcdn.net/ajax/libs/echarts/4.7.0/echarts-en.common.js"></script>用着官方给的案例还可以&#xff0c;但是一用gallery社区里面的例子就报错 后来经过不断调试终于知道是需要换个cdn&…

认识微软Visual Studio Tools for AI

微软已经发布了其 Visual Studio Tools for AI 的测试版本&#xff0c;这是微软 Visual Studio 2017 IDE 的扩展&#xff0c;可以让开发人员和数据科学家将深度学习模型嵌入到应用程序中。Visual Studio Tools for AI 工具同时支持 Microsoft 的 Cognitive Toolkit 和 Google 的…

mybatis源码阅读(一):SqlSession和SqlSessionFactory

转载自 mybatis源码阅读(一)&#xff1a;SqlSession和SqlSessionFactory 一、接口定义 听名字就知道这里使用了工厂方法模式&#xff0c;SqlSessionFactory负责创建SqlSession对象。其中开发人员最常用的就是DefaultSqlSession &#xff08;1&#xff09;SqlSession接口定义…

开源纯C#工控网关+组态软件(六)图元组件

一、 图元概述 图元是构成人机界面的基本单元。如一个个的电机、设备、数据显示、仪表盘&#xff0c;都是图元。构建人机界面的过程就是铺排、挪移、定位图元的过程。 图元设计是绘图和编码的结合。因为图元不仅有显示和动画&#xff0c;还有背后操纵动画的控制逻辑。 一个好…