问:


I was using HttpWebRequest to try a rest api in ASP.NET Core MVC.
Here is my HttpWebRequest client code:

HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://localhost:55161/Home/Testing");

string data;
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
using (StreamReader reader = new StreamReader(resp.GetResponseStream(), System.Text.Encoding.UTF8))
{
data = reader.ReadToEnd();
}

If I used StreamWriter to write a message to Response.Body in an ASP.NET Core controller, everything is fine:

using (var streamWriter = new StreamWriter(Response.Body, System.Text.Encoding.UTF8))
{
streamWriter.Write("hello");
streamWriter.Flush();
}

But if I used Response.Body.Write embedded in a StreamWriter block to write the same message, there will be a weird 65279 character in the end of the string "hello" when I got it from my client code.

using (var streamWriter = new StreamWriter(Response.Body, System.Text.Encoding.UTF8))
{
byte[] data = System.Text.Encoding.UTF8.GetBytes("hello");
Response.Body.Write(data, , data.Length);
}

I want to know if this is a bug or any mechanism caused this problem?
I didn't use UseBrowserLink in startup and my ASP.NET Core version is 2.1

答:


there will be a weird 65279 character in the end of the string "hello" when I got it from my client code

You mean something like this?

hello

This is expected based on the code you provided. Why are you wrapping the stream in a StreamWriter, then writing to the stream directly?

The StreamWriter has a buffer that it will flush to the output when you close it. This will cause a lot of problems if you've been writing to the stream directly. Specifically, what's happening here is this:

  1. You wrap the Stream in the StreamWriter
  2. You write hello directly to the stream
  3. The StreamWriter is closed, so it flushes it's (empty) buffer.
  4. Since you are using the Encoding.UTF8 encoding, the StreamWriter writes a UTF-8 Byte Order Mark (the sequence 0xEF 0xBB 0xBF which appears as  unless it's at the very beginning of the stream) to the stream. Since you've already written hello, this appears after your hello, causing the rendering glitch above.

因此我们可以看到,在使用StreamWriter的时候,千万不要又用代码直接往StreamWriter底层的Stream对象(本例中是Response.Body)写入数据,因为这很有可能会导致StreamWriter错误地将UTF-8编码的BOM(Byte Order Mark)加到了你写入数据的后面,而UTF-8编码的BOM(Byte Order Mark)只能够出现在一个Stream最开头才能被正确地识别,否则会被识别为乱码,如同本例中的hello一样。

原文链接

StreamWriter结合UTF-8编码使用不当,会造成BOM(Byte Order Mark )问题生成乱码(转载)的更多相关文章

  1. 从Java String实例来理解ANSI、Unicode、BMP、UTF等编码概念

    转(http://www.codeceo.com/article/java-string-ansi-unicode-bmp-utf.html#0-tsina-1-10971-397232819ff9a ...

  2. 编码总结,以及对BOM的理解

    一.前言 在跨平台.跨操作系统或者跨区域之间,经常会涉及到编码的问题,因为前段时间在项目中,遇到了因为编码而产生乱码的问题,以前对编码也是一知半解,所以决定对编码有一个更为深入的了解,因此才有了这篇自 ...

  3. StreamWriter(ms, new UTF8Encoding(false))可以达到不输出BOM的需求。

    winform 通过webservice向服务器提交图片需要注意的地方 最近一个winform项目中需要通过拍照或者上传本地文件或者截图的方式把产品图片上传到服务器,最后选择了服务器部署webserv ...

  4. C#中中文编码的问题(StreamWriter和StreamReader默认编码)

    在使用StreamWriter和StreamReader时产生了这样的疑问,在不指定的情况下,他们使用什么编码方式? 查看MSDN,请看下图: 注意红色区域  这让我以为构造函数参数不同时使用不一样的 ...

  5. 编码占用的字节数 1 byte 8 bit 1 sh 1 bit 中文字符编码 2. 字符与编码在程序中的实现 变长编码 Unicode UTF-8 转换 在网络上传输 保存到磁盘上 bytes

    小结: 1.UNICODE 字符集编码的标准有很多种,比如:UTF-8, UTF-7, UTF-16, UnicodeLittle, UnicodeBig 等: 2 服务器->网页 utf-8 ...

  6. Python核心编程--学习笔记--6--序列(上)字符串

    本章研究Python中的序列:字符串.列表和元组.因为这些类型其实都是由一些成员共同组成的一个序列整体,所以我们把它们统称为序列.序列的存储结构可以表示为: 1 序列 序列类型有着相同的访问模式:按下 ...

  7. pthon核心编程-读书笔记:知识点摘录与总结(方便理解和快速记忆)

    Python 中的列表(大小可变的数组)和字典(哈希表)就是内建于语言本身的.在核心语言中提供这些重要的构建单元,可以鼓励人们使用它们, 缩短开发时间与代码量,产生出可读性更好的代码.C不提供, c+ ...

  8. unicode编码与utf-8 区别

    unicode编码与utf-8 区别 如果是为了跨平台兼容性,只需要知道,在 Windows 记事本的语境中: 所谓的「ANSI」指的是对应当前系统 locale 的遗留(legacy)编码.[1] ...

  9. python的编码问题

    本文简单介绍了各种常用的字符编码的特点,并介绍了在python2.x中如何与编码问题作战 :) 请注意本文关于Python的内容仅适用于2.x,3.x中str和unicode有翻天覆地的变化,请查阅其 ...

随机推荐

  1. andriod 支付宝类似界面图片加文字

    <?xml version="1.0" encoding="utf-8"?> <GridView xmlns:android="ht ...

  2. VS2010 MFC中 给菜单项添加消息响应函数

    久了没用,居然忘记了该怎样给菜单项添加响应函数了~~~~~~~~T_T 特记于此: 1. 在资源视图的Menu里找到自己要添加的菜单,然后输入菜单项. 2. 右击菜单项选属性,设置Popup为Fals ...

  3. SilverLight-DataBinding-DataTemplates: 三、数据绑定 DataTemplates模板的使用(求助,没有到达实例效果,求高人指点迷津)

    ylbtech-SilverLight-DataBinding-DataTemplates: 三.数据绑定 DataTemplates模板的使用 1.A, Data Templates Intro(数 ...

  4. 给控件做数字签名之一:将控件打包为Web发布包 [转]

    微软代码签名证书使用指南 http://www.wotrust.com/support/signcode_guide.htm 签名重要性:http://www.wotrust.com/FAQ/whyS ...

  5. 2016.11.29 activiti实战--第19章--统一身份管理(含自定义用户与数组的实现)

    学习资料:<Activiti实战> 第十九章 统一身份管理 本章讲解如何统一业务系统与activiti的用户管理系统. 第5章的时候已经讲解过activiti的用户与组.一般来说业务系统都 ...

  6. 2017.2.9 开涛shiro教程-第十章-会话管理(一)

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 第十章 会话管理(一) 10.1 会话 shiro提供的会话可以用 ...

  7. 【原创】SM4password算法源代码接口具体解释

    [原创]SM4password算法源代码接口具体解释 近期几天想把cryptdb的加密算法换成国产的sm4加密算法.所以花了时间研究了一下sm4的源代码和基本原理,避免忘记,写下这篇博客以作记录. 先 ...

  8. 奇怪!post提交 地址栏参数竟然可见

    转:    http://blog.csdn.net/yuebinghaoyuan/article/details/7727802 在做项目中,form标签中method="post&quo ...

  9. 【AngularJS】Yeoman安装

    看不到PPT的请自行解决DNS污染问题.

  10. project 的用法

    任务和子任务,树状结构: 点击一个绿色的箭头就可以实现. 时间的话:视图→甘特图→双击“开始时间”修改即可