ASP.NET Core 中的SEO优化(2):中间件中渲染Razor视图
前言
上一篇文章《ASP.NET Core 中的SEO优化(1):中间件实现服务端静态化缓存》中介绍了中间件的使用方法、以及使用中间件实现服务端静态化缓存的功能。本系列文章的这些技巧都是我最近在做的公司实际项目中的一些奇怪的需求之后总结而来的……
要解决的问题
好了,本篇说说如何在中间件中渲染Razor视图。之所以会有这个技巧,是因为我们有个需求:
需要在所有返回404状态的路由都输出一个特定视图。
比如当有id=1的文章,而没有id=2的文章时,那么/url/1.html展示文章详情页,/url/2.html展示404视图。
所以,要实现这个需求只有两种办法:
- 当文章查找不到时直接执行
return View("404")返回404视图。- 在中间件中执行完MVC的处理之后检查返回状态,如果是错误状态就直接渲染视图并输出。
由于CMS系统中不止一处需要返回404状态,所以因为用代码整洁作为懒惰的借口,决定尝试第二个方法。
实现
实现方式很简单,就是在Configure中注入ICompositeViewEngine实例,构造视图上下文,再渲染视图为字符串,最后输出。其它的分析就在代码注释中说明吧。
直接上代码:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ICompositeViewEngine engine)
{
app.Use(async (context, next) =>
{
//因为只是在请求最后处理,所以这里直接就运行下一个中间件
await next();
//返回后检查是否出现错误的状态
if (context.Response.StatusCode >= 400)
{
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
//ContentType设置为text/html,使浏览器以正常页面的格式显示
context.Response.ContentType = "text/html";
//指向特定的视图
var viewResult = engine.GetView("~/", "~/Views/Default/Home/Error.cshtml", true);
if (!viewResult.Success)
await context.Response.WriteAsync("OMG! 连错误视图都找不到了。。");
//创建临时的StringWriter实例,用来配置到视图上下文中
using (var output = new StringWriter())
{
//视图上下文对于视图渲染来说很重要,视图中的前后台交互都需要它
var viewContext = new ViewContext()
{
HttpContext = context,
Writer = output,
RouteData = new Microsoft.AspNetCore.Routing.RouteData()
{
//RouteData在这里传入视图,这样视图可以显示错误信息之类的数据
},
View = viewResult.View,
FormContext = new FormContext(),
ActionDescriptor = new Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor()
};
//渲染
await viewResult.View.RenderAsync(viewContext);
//输出到响应体
await context.Response.WriteAsync(output.ToString());
}
}
});
//后面是Mvc的中间件,执行Mvc的处理
//...app.UseMvc
}
总结
这个技巧还能用于单页面应用程序的路由重定向,把所有路由都输出入口页面代码。
ASP.NET Core 中的SEO优化(2):中间件中渲染Razor视图的更多相关文章
- ASP.NET Core 中的SEO优化(4):自定义视图路径及主题切换
系列回顾 <ASP.NET Core 中的SEO优化(1):中间件实现服务端静态化缓存> <ASP.NET Core 中的SEO优化(2):中间件中渲染Razor视图> < ...
- ASP.NET Core 中的SEO优化(3):自定义路由匹配和生成
前言 前两篇文章主要总结了CMS系统两个技术点在ASP.NET Core中的应用: <ASP.NET Core 中的SEO优化(1):中间件实现服务端静态化缓存> <ASP.NET ...
- 创建ASP.NET Core MVC应用程序(4)-添加CRUD动作方法和视图
创建ASP.NET Core MVC应用程序(4)-添加CRUD动作方法和视图 创建CRUD动作方法及视图 参照VS自带的基架(Scaffold)系统-MVC Controller with view ...
- ASP.NET Core 中的SEO优化(1):中间件实现服务端静态化缓存
分享 最近在公司成功落地了一个用ASP.NET Core 开发前台的CMS项目,虽然对于表层的开发是兼容MVC5的,但是作为爱好者当然要用尽量多的ASP.NET Core新功能了. 背景 在项目开发的 ...
- ASP.NET Core 数据保护(Data Protection)【中】
前言 上篇主要是对 ASP.NET Core 的 Data Protection 做了一个简单的介绍,本篇主要是介绍一下API及使用方法. API 接口 ASP.NET Core Data Prote ...
- 制作移动端手机网站过程中的SEO优化方法技巧
据国内三大运营商数据来看,中国的手机用户数已达10亿,超过2/5的移动用户每个月都会从手机终端访问网页,如今的移动端手机网站比例肯定有提升,但是对于这些存在的移动版本网站来说,马海祥查看了很大一部分手 ...
- ASP.NET CORE MVC 2.0 如何在Filter中使用依赖注入来读取AppSettings,及.NET Core控制台项目中读取AppSettings
问: ASP.NET CORE MVC 如何在Filter中使用依赖注入来读取AppSettings 答: Dependency injection is possible in filters as ...
- 探索ASP.Net Core 3.0系列六:ASP.NET Core 3.0新特性启动信息中的结构化日志
前言:在本文中,我将聊聊在ASP.NET Core 3.0中细小的变化——启动时记录消息的方式进行小的更改. 现在,ASP.NET Core不再将消息直接记录到控制台,而是正确使用了logging 基 ...
- asp.net core 3.1 入口:Program.cs中的Main函数
本文分析Program.cs 中Main()函数中代码的运行顺序分析asp.net core程序的启动,重点不是剖析源码,而是理清程序开始时执行的顺序.到底用了哪些实例,哪些法方. asp.net c ...
随机推荐
- Android开发-网络通信2
调试了三种通信方法:HttpClient.AsyncHttpClient 和 Volley . HttpClient 测试代码[1]: public class HttpUtil { public s ...
- 【三小时学会Kubernetes!(四) 】Deployment实践
Deployment 部署 Kubernetes 部署可以帮助每一个应用程序的生命都保持相同的一点:那就是变化.此外,只有挂掉的应用程序才会一尘不变,否则,新的需求会源源不断地涌现,更多代码会被开发出 ...
- 欢迎来到 Flask 的世界
欢迎来到 Flask 的世界 欢迎阅读 Flask 的文档.本文档分成几个部分,我推荐您先读 < 安装 >,然后读< 快速上手 >.< 教程 > 比快速上手文档更详 ...
- C# 终于写完了简单的ORM
实现单表 增 .删. 改 .查 使用接口定义表实体数据.实体对象动态创建,使用 Email 进行数据读取. 存储过程调用示例
- SqlServer 转 Oracle 的几点注意
(转自:http://www.2cto.com/database/201208/146740.html) 1.字符型的字段相加需要用“||”,如果用“+”的话,会报“无效的数字”的错误. 2.类似 ...
- 拒绝了对对象 'sp_OACreate' (数据库 'mssqlsystemresource',架构 'sys')的 EXECUTE 权限。
执行一个存储过程, 由于里面使用到了一些 --创建对象 EXEC sp_OACreate 'VBScript.RegExp', @objRegex OUT --设置属性 EXEC sp_OASe ...
- 2: 使用Prism初始化程序 Initializing Applications Using the Prism Library 5.0 for WPF(英汉对照版)
This topic addresses what needs to happen to get a Prism for WPF application up and running. A Prism ...
- 怎样安装 OpenJDK 8 in Ubuntu 14.04 & 12.04 LTS
OpenJDK Java 8 has been made into official Ubuntu repositories for 14.10 Utopic and higher. For Ubun ...
- zset类型以及其操作
sorted set类型 sorted sets类型以及其操作zset是set的一格升级版本,它在set的基础上增加了一格顺序属性,这一属性在添加元素的同时可以指定,每次指定后,zset会自动重新按照 ...
- H.264采集、编码、传输的流程
转载自H.264采集.编码.传输的流程 1 采集到的原始数据放入buf中 2 转化为yuv格式放入yuv conv.RGB24_to_YV12(buf, yuv,IMAGE_WIDTH, IMAGE_ ...