有园友在博问中提了这样一个问题 —— .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的魅力。

更新1:根据 零度的火 的评论,更好的解决方法是

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

更新2:后来发现更好的解决方法

services.Configure<WebEncoderOptions>(options =>
options.TextEncoderSettings = new TextEncoderSettings(UnicodeRanges.BasicLatin,
UnicodeRanges.CjkUnifiedIdeographs));

转自:http://www.cnblogs.com/dudu/p/5879913.html

【转】依赖注入的威力,.NET Core的魅力:解决MVC视图中的中文被html编码的问题的更多相关文章

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

    有园友在博问中提了这样一个问题 —— .NET Core 中文等非英文文字html编码输出问题,到我们的 ASP.NET Core 项目中一看,也是同样的问题. 比如下面的Razor视图代码: @{ ...

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

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

  3. ASP。使用依赖注入的asp.net Core 2.0用户角色库动态菜单管理

    下载source code - 2.2 MB 介绍 在开始这篇文章之前,请阅读我的前一篇文章: 开始使用ASP.NET Core 2.0身份和角色管理 在上一篇文章中,我们详细讨论了如何使用ASP.N ...

  4. Asp.Net Core 项目实战之权限管理系统(4) 依赖注入、仓储、服务的多项目分层实现

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

  5. ASP.NET Core 中文文档 第三章 原理(10)依赖注入

    原文:Dependency Injection 作者:Steve Smith 翻译:刘浩杨 校对:许登洋(Seay).高嵩 ASP.NET Core 的底层设计支持和使用依赖注入.ASP.NET Co ...

  6. net core 依赖注入问题

    net core 依赖注入问题 最近.net core可以跨平台了,这是一个伟大的事情,为了可以赶上两年以后的跨平台部署大潮,我也加入到了学习之列.今天研究的是依赖注入,但是我发现一个问题,困扰我很久 ...

  7. ASP.NET Core 依赖注入(DI)简介

    ASP.NET Core是从根本上设计来支持和利用依赖注入. ASP.NET Core应用程序可以通过将其注入到Startup类中的方法中来利用内置的框架服务,并且应用程序服务也可以配置为注入. AS ...

  8. ASP.NET Core 2.0 : 六. 举个例子来聊聊它的依赖注入

    本文通过一个维修工与工具库的例子形象的描述一下为什么要用依赖注入.它的工作原理是什么样的, 然后根据这个类比一下ASP.NET Core 中的依赖注入, 从而深刻了解它的使用方法.注意事项以及回收机制 ...

  9. [译]ASP.NET Core依赖注入深入讨论

    原文链接:ASP.NET Core Dependency Injection Deep Dive - Joonas W's blog 这篇文章我们来深入探讨ASP.NET Core.MVC Core中 ...

随机推荐

  1. 编译jmeter5.0源码

    jmeter5.0使用过程中,遇到request或者response乱码的情况,想要一次性解决这个问题,需要编译ApacheJMeter_http.jar这个包(lib\ext文件下)里的Reques ...

  2. spring源码解析1--spring整体架构

    一.Spring整体架构图 关于Spring的基本介绍就不再赘述了,先展示Spring框架的整体架构图如下示: 二.Spring结构介绍 Spring主要分为Core Container.Test.D ...

  3. 用Java实现图片验证码功能

    一.什么是图片验证码? 可以参考下面这张图: 我们在一些网站注册的时候,经常需要填写以上图片的信息. 1.图片生成实体类: package com.hexianwei.graphic; import ...

  4. C# 解析html中筛选class的问题

    C# 解析html中筛选class的问题 C# html解析 class 类  当我们用C#的.net解析html的时候,当html的元素没有id,并且没有过多的属性供筛选,只能通过class=&qu ...

  5. vue 3.0的搭建

    1. 删除以前的vue 2.x版本,并下载3.x版本 npm uninstall -g vue-cli / yarn global remove vue-cli npm install -g @vue ...

  6. Weekly Contest 126

    前两周一直是一道,都不好意思写了.这周终于题目简单了,刷了三道. 1002. Find Common Characters Given an array A of strings made only ...

  7. java字符串对象存储机制

    String s1="abc";创建了几个String对象 ? String s2 = new String("abc");创建了几个String对象? s1= ...

  8. ensp 单臂路由实验

    搭建如下拓扑 交换机: 创建vlan10 20 g0/0/1接口设置访问类型为access,加入到vlan10:g0/0/2接口设置访问类型为access,加入到vlan20 g0/0/3接口设置为t ...

  9. image management in kubernet

    Image How can I edit an existing docker image metadata? docker-copyedit Registry Disk kubevirtis a g ...

  10. word模板导出的几种方式:第一种:占位符替换模板导出(只适用于word中含有表格形式的)

    1.占位符替换模板导出(只适用于word中含有表格形式的): /// <summary> /// 使用替换模板进行到处word文件 /// </summary> public ...