1. 首页
  2. 文章列表
  3. 解决ASP.NET Core MVC的Razor视图渲染中文乱码的问题

同样也是在迁移.NET Framework项目到.NET Core时踩的一个坑,在我以为已经迁移完成的时候,在浏览器里偶然按下Ctrl+U时发现,我的中文呢,怎么全是Unicode编码,然后导致的问题就是弹出的模态框,也是Unicode编码的中文字;

懒得勤快的博客_全栈开发者_互联网分享精神

然后,Fuck,怎么回事,又陷入了沉思

懒得勤快的博客_全栈开发者_互联网分享精神

于是又新开一个项目来研究这到底是为什么?

我新建了一个最简单的razor视图

@{
    string str = "懒得勤快的博客";
}
欢迎来到 @str

程序跑起来之后,浏览器看到确实没什么问题

懒得勤快的博客_全栈开发者_互联网分享精神

但是Ctrl+U,乍一看,变量部分变成了Unicode编码,这肯定不是我想要的样子啊!

懒得勤快的博客_全栈开发者_互联网分享精神

怎么办?又去微软网站扒文档,发现.NET Core的@符相当于下面这样的代码:

@Html.Raw(Html.Encode(str))

这就好理解了,中文确实是被Unicode编码了,但是,我要挨着去把每处用@符渲染的文本都改成@Html.Raw(str)这样写么?那我不得疯掉?!

这肯定是有解决办法的,于是,我想到了反编译,把Html.Encode通过Resharper反编译后,发现其核心代码简化之后是这样的:

private readonly IHtmlGenerator _htmlGenerator;
public string Encode(string value)
{    
    return _htmlGenerator.Encode(value);
}

它其实是调用了接口类IHtmlGenerator的Encode方法, 但是,这好像没什么用?继续反编译,发现这玩意儿好像不是MVC里面的,因为命名空间在System.Text.Encodings.Web下,为了确保是不是它的锅,我写了个简单的控制台程序来验证:

public class Program
{
    public static void Main(string[] args)
    {            
        string s=HtmlEncoder.Default.Encode("懒得勤快");
        Console.WriteLine(s);
    }
}

输出结果:

懒得勤快的博客_全栈开发者_互联网分享精神

看来确实是它的锅;而且在HtmlEncoder点的时候,除了Default,Resharper还给我建议了两个Create方法,那看看Create是什么效果吧;

在点Create方法的时候,需要传入参数,它需要一个UnicodeRange类型的参数,那我输入UnicodeRange然后智能提示一下,Resharper给了我一堆的参数;

懒得勤快的博客_全栈开发者_互联网分享精神

我看到了有个All,那就用它吧!

于是,代码改成了这样:

public class Program
{
    public static void Main(string[] args)
    {            
        string s=HtmlEncoder.Create(UnicodeRanges.All).Encode("懒得勤快");
        Console.WriteLine(s);
    }
}

跑起来一看,这个没问题!

懒得勤快的博客_全栈开发者_互联网分享精神

然后想想怎么让razor用HtmlEncoder.Create(UnicodeRanges.All)去渲染文本,先研究下HtmlEncoder.Default是怎么被创建的,继续反编译,发现HtmlEncoder.Default的创建是这样的:

懒得勤快的博客_全栈开发者_互联网分享精神

原来字符集用的是BasicLatin,难怪中文显示乱码,背你妈的时,为什么不用UnicodeRanges.All???为了节省几个字节的内存么?!

既然找到问题了,那离解决问题又进了一步,怎么替换掉HtmlEncoder.Default,让MVC去调HtmlEncoder.Create(UnicodeRanges.All)?

回到最初的反编译结果,去反编译看 MVC HtmlGenerator的源码;

public DefaultHtmlGenerator(IAntiforgery antiforgery,IOptions<MvcViewOptions> optionsAccessor,IModelMetadataProvider metadataProvider,IUrlHelperFactory urlHelperFactory,HtmlEncoder htmlEncoder,ClientValidatorCache clientValidatorCache)
{
}

这是一种很熟悉的写法!肯定是依赖注入来的!是不是我重新注入一个HtmlEncoder实例,覆盖掉原来的,就可以了?那我先试试看吧,在Startup.cs里面加了一行:

services.AddSingleton(HtmlEncoder.Create(UnicodeRanges.All));

重新把代码跑起来,奇迹的发现,问题解决了!

懒得勤快的博客_全栈开发者_互联网分享精神

顺便也找到了网上更好地解决方案:

services.Configure<WebEncoderOptions>(options =>options.TextEncoderSettings = new TextEncoderSettings(UnicodeRanges.All));

这问题肯定不是我一个人遇到

分享到:

版权声明:

本文仅用于学习、研究和交流目的,欢迎非商业性质转载。本文链接:https://masuit.com/1436

l  博主在此发文(包括但不限于汉字、拼音、拉丁字母)均为随意敲击键盘所出,用于检验本人电脑键盘录入、屏幕显示的机械、光电性能,并不代表本人局部或全部同意、支持或者反对观点。如需要详查请直接与键盘生产厂商法人代表联系。挖井挑水无水表,不会网购无快递。

l  文章内容部分来源于互联网,不代表本人的任何立场;涉及到的软件来源于互联网,仅供个人下载使用,请勿用于商业用途,版权归软件开发者所有,下载后请于24小时内删除,如有真实需要请支持正版!因下载本站任何资源造成的损失,全部责任由使用者本人承担!如果你是版权方,认为本文内容对您的权益有所侵犯,请联系博主,并参照侵删联系的说明提交相应的证明材料,待博主进行严格地审查和背景调查后,情况属实的将在三天内将本文删除或修正。

l  博主的文章没有高度、深度和广度,只是凑字数。由于博主的水平不高(其实是个菜B),不足和错误之处在所难免,希望大家能够批评指出。

l  博主是利用读书、参考、引用、抄袭、复制和粘贴等多种方式打造成自己的纯镀 24k 文章,请原谅博主成为一个无耻的文档搬运工!

l  博主只是一名普通的互联网从业者,不会帮你盗号,不懂破解开机密码,找不回你丢失的手机等,如有这样的想法我也帮你实现不了!

相关推荐:

一小时学会 C#6.0 的新特性 博主的又一开源项目——基于EntityFrameworkCore和Lucene.NET实现的全文搜索引擎库
C#经典面试题——深入理解IEnumerable和IQueryable两接口的区别 深入理解C#中的IDisposable接口
用C#实现求有向图的最长路径和最短路径 浅谈MVC的Attribute路由,教你一步一步设计出漂亮的路由
.NET/java Office组件神器——Aspose.Total 17.x/18.x破解版+破解补丁下载 ASP.NET Core SignalR 实时推送框架简单入门教程+服务端主动推送案例
浅谈http断点续传的原理以及.NET代码实现,看似挺高端,其实很简单 C# vs Java:C# 五个不可替代的特性瞬间秒杀 Java

评论区:

    还没有评论哦,赶紧来写评论吧