搜文章
推荐 原创 视频 Java开发 iOS开发 前端开发 JavaScript开发 Android开发 PHP开发 数据库 开发工具 Python开发 Kotlin开发 Ruby开发 .NET开发 服务器运维 开放平台 架构师 大数据 云计算 人工智能 开发语言 其它开发
Lambda在线 > dotNET跨平台 > 中间件中渲染Razor视图

中间件中渲染Razor视图

dotNET跨平台 2017-11-28

前言

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

要解决的问题

好了,本篇说说如何在中间件中渲染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. }

总结

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

相关文章:


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


版权声明:本站内容全部来自于腾讯微信公众号,属第三方自助推荐收录。《中间件中渲染Razor视图》的版权归原作者「dotNET跨平台」所有,文章言论观点不代表Lambda在线的观点, Lambda在线不承担任何法律责任。如需删除可联系QQ:516101458

文章来源: 阅读原文

相关阅读

关注dotNET跨平台微信公众号

dotNET跨平台微信公众号:opendotnet

dotNET跨平台

手机扫描上方二维码即可关注dotNET跨平台微信公众号

dotNET跨平台最新文章

精品公众号随机推荐