有园友在博问中提了这样一个问题 —— .NET Core 中文等非英文文字html编码输出问题,到我们的 ASP.NET Core 项目中一看,也是同样的问题。

比如下面的Razor视图代码:

@{ViewBag.Title = "代码改变世界";
}<title>@ViewBag.Title</title>

输出的html代码变成了:

<title>代码改变世界</title>

上面的 @ViewBag.Title 实际上等同于下面的代码:

@Html.Raw(Html.Encode(ViewBag.Title))

所以解决这个问题需要从ASP.NET Core MVC中的HtmlHelper下手(上面代码中Html的类型就是HtmlHelper)。

从GitHub上签出MVC的源代码看看HtmlHelper.Encode()的实现:

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

实际调用的是IHtmlGenerator接口的Encode()方法,MVC中实现这个接口的是DefaultHtmlGenerator,其对应的Encode()实现代码如下:

private readonly HtmlEncoder _htmlEncoder;public string Encode(string value)
{    return !string.IsNullOrEmpty(value) ? _htmlEncoder.Encode(value) : string.Empty;
}

原来真正干活的主角是HtmlEncoder,但它不是在MVC中实现的,而是在.NET Core Framework中实现的,命名空间是 System.Text.Encodings.Web 。

写个.NET Core控制台程序直接调用HtmlEncoder看看是不是就是它惹的祸。

public class Program
{    public static void Main(string[] args){            Console.WriteLine(HtmlEncoder.Default.Encode("代码改变世界"));}
}

输出结果与MVC中是同样的问题。

试试不用默认的HtmlEncoder实例(HtmlEncoder.Default),而是自己调用HtmlEncoder.Create()方法创建实例,这时发现了UnicodeRange参数类型。

public static HtmlEncoder Create(params UnicodeRange[] allowedRanges);

当使用UnicodeRanges.All作为参数创建HtmlEncoder实例时,问题就解决了。

Console.WriteLine(HtmlEncoder.Create(UnicodeRanges.All).Encode("代码改变世界"));

紧接着从GitHub上签出System.Text.Encodings.Web的源代码,看看HtmlEncoder.Default对应的HtmlEncode实例是如何被创建的:

internal readonly static DefaultHtmlEncoder Singleton = new DefaultHtmlEncoder(new TextEncoderSettings(UnicodeRanges.BasicLatin));

原来用的是UnicodeRanges.BasicLatin,难怪中文会被编码,搞不懂为什么默认不用UnicodeRanges.All?

知道了问题的原因,解决起来就不难了,只要我们以HtmlEncoder.Create(UnicodeRanges.All)创建HtmlEncoder实例,并替换掉MVC中所用的默认HtmlEncoder实例。那如何替换呢?

回到MVC的源代码中,看看DefaultHtmlGenerator的实现,发现它的构造函数参数中有HtmlEncoder:

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

根据.NET从上到下、由内而外全面依赖注入的秉性,这个地方应该也是依赖注入的,我们只需注入一个新的HtmlEncoder实例即可,是不是这样呢?

码上一行,你就知道。

在 Startup.cs 的 ConfigureServices() 方法中添加下面的一行代码:

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

运行ASP.NET Core站点,输出结果如下:

<title>代码改变世界</title>

一行注入,立马解决。依赖注入的威力,.NET Core的魅力。

依赖注入的威力,.NET Core的魅力:解决MVC视图中的中文被html编码的问题相关推荐

  1. .NET Core解决MVC视图中的中文被html编码的问题

    在  .net core mvc 视图输出 变量的时候 默认使用的是 UnicodeRanges.BasicLatin  进行的编码 所以 输出中文后在查看源码的时候是进过编码了的 . 解决方案 在 ...

  2. 使用依赖注入的ASP.NET Core 2.0用户角色基础动态菜单管理

    目录 介绍 背景 先决条件 使用代码 第1步 - 创建数据库 创建数据库 第2步 - 创建ASP.NET Core 更新appsettings.json 步骤3 - 在Startup.cs文件中添加I ...

  3. php 身份认证 claim,asp.net core cookie身份认证view视图中读取/读取User.Claims中的值实例...

    假设claim如下,q为查询出来的用户表结果集 var claims = new List(){ new Claim("UserId", q.Id.ToString()), new ...

  4. 一文读懂Asp.net core 依赖注入(Dependency injection)

    一.什么是依赖注入 首先在Asp.net core中是支持依赖注入软件设计模式,或者说依赖注入是asp.net core的核心: 依赖注入(DI)和控制反转(IOC)基本是一个意思,因为说起来谁都离不 ...

  5. 【ASP.NET Core】依赖注入高级玩法——如何注入多个服务实现类

    依赖注入在 ASP.NET Core 中起中很重要的作用,也是一种高大上的编程思想,它的总体原则就是:俺要啥,你就给俺送啥过来.服务类型的实例转由容器自动管理,无需我们在代码中显式处理. 因此,有了依 ...

  6. ASP.NET Core Web 应用程序系列(一)- 使用ASP.NET Core内置的IoC容器DI进行批量依赖注入(MVC当中应用)...

    在正式进入主题之前我们来看下几个概念: 一.依赖倒置 依赖倒置是编程五大原则之一,即: 1.上层模块不应该依赖于下层模块,它们共同依赖于一个抽象. 2.抽象不能依赖于具体,具体依赖于抽象. 其中上层就 ...

  7. asp.net core自定义依赖注入容器,替换自带容器

    依赖注入 在asp.net core程序中,众所周知,依赖注入基本上贯穿了整个项目,以通用的结构来讲解,控制器层(Controller层)依赖业务层(Service层),业务层依赖于仓储层(Repos ...

  8. ASP.NET Core - 在ActionFilter中使用依赖注入

    上次ActionFilter引发的一个EF异常,本质上是对Core版本的ActionFilter的知识掌握不够牢固造成的,所以花了点时间仔细阅读了微软的官方文档.发现除了IActionFilter.I ...

  9. ASP.NET Core 中的依赖注入

    什么是依赖注入 软件设计原则中有一个依赖倒置原则(DIP),为了更好的解耦,讲究要依赖于抽象,不要依赖于具体.而控制反转(Ioc)就是这样的原则的其中一个实现思路, 这个思路的其中一种实现方式就是依赖 ...

最新文章

  1. 网络广告计费方式常用术语
  2. Python 之 matplotlib (十三) subplot分格显示
  3. Bete冲刺第五阶段
  4. 简单实现Dedecms RSS全站输出
  5. C++对于文件的相关操作 创建、读写、删除代码
  6. netty客户端源码
  7. 又一台苹果第一代电脑顺利拍卖:成交价超过47万美元
  8. 图像调优1:清晰度相关参数MTF,SFR,MTF50,MTF50P 以及TVL的概念以及换算说明
  9. 红米K30、K40所有版本获取root教程,理论上支持所有小米手机(超级详细,附带原理解释)
  10. trajan 算法 离线求lca 超详细讲解~~~~ 保证一看就懂~~~
  11. 计算机打印机图标删除吗,打印机图标不见了怎么办 打印机图标消失的解决方法...
  12. 三次方程求根公式例子
  13. 解决雅虎邮箱使用outlook只能收不能发送的问题(针对yahoo.com.cn)
  14. 计算机中常用于比较的图表有,2013年职称计算机Excel考点:常用图表类型
  15. Xcode10 开启暗黑模式(dark mode)
  16. 数据解读:​影视行业是不是没编剧了,怎么老是在翻拍网络小说?
  17. Cisco NAC介绍
  18. 移动u盘装linux移动系统下载,(把Linux装进U盘打造最简洁移动系统.doc
  19. Speedoffice(PPT)如何更改配色方案
  20. Android 监听U盘OTG挂载状态

热门文章

  1. Win10系统修改MAC地址
  2. LDAP启动cacao提示Invalid file permission
  3. 通过电话号码获取姓名 (+86或者飞信)
  4. APP-V5.0的Sequencer过程
  5. 给IT新人的15个建议:苦逼程序员的辛酸反省与总结
  6. 介绍这个库:C# Blazor中显示Markdown文件
  7. ASP.NET Web API中实现版本
  8. ABP Vnext 4.4:统一Ef Core的DbContext/移除EF Core Migrations项目
  9. 记一次 .NET 某云采购平台API 挂死分析
  10. 合肥.NET俱乐部第二期技术沙龙活动预告