IIS是否执行非法字符replace? 如果是的话,如何阻止它?

上下文:在IIS中运行的ASP.NET MVC,带有一个UTF-8%编码的URL。

使用标准项目模板和HomeController的testing操作,如下所示:

 public ActionResult Test(string id) { return Content(id, "text/plain"); } 

对于大多数%编码的UTF-8路由来说,这是正常的,比如:

 http://mydevserver/Home/Test/%e4%ba%ac%e9%83%bd%e5%bc%81 

预期成果京都弁

但是使用路线:

 http://mydevserver/Home/Test/%ee%93%bb 

url没有被正确接收。

除此之外: %ee%93%bb是%编码的代码点0xE4FB; 基本多语言平面,私人使用区域; 但最终 – 一个有效的unicode代码点; 你可以手动validation,或通过:

 string value = ((char) 0xE4FB).ToString(); string encoded = HttpUtility.UrlEncode(value); // %ee%93%bb 

现在,接下来发生的事情取决于networking服务器。 在Visual Studio开发服务器(又名cassini)上,接收到正确的id – 长度为1的string,其中包含代码点0xE4FB。

但是,如果我在IIS或IIS Express中执行此操作,则会得到一个不同的id ,特别是"î“»" ,代码点:0xEE,0x201C,0xBB。 你会立刻认出第一个和最后一个是我们百分比编码的string的开始和结束……所以中间发生了什么?

好:

  • 代码点0x93是 ( 源 )
  • 代码点0x201c是 ( 源 )

它看起来非常像IIS在处理我的url时执行了某种引用转换。 现在,也许这可能在几个场景中使用(我不知道),但是当它发生在%编码的UTF-8块的中间时肯定是一件坏事。

请注意, HttpContext.Current.Request.Raw 显示这个翻译已经发生,所以这看起来不像一个MVC的bug; 请注意Darin的评论,强调它在URL的path和查询部分中的工作方式不同。

所以(双方):

  1. 我的分析是缺less一些重要的微妙的Unicode / URL处理?
  2. 我如何解决它? (即,使我得到预期的性格)
 id = Encoding.UTF8.GetString(Encoding.Default.GetBytes(id)); 

这会给你你的原始身份证。 IIS使用默认(ANSI)编码path字符。 你的url编码的string被解码使用,这就是为什么你得到一个奇怪的事情回来。

要得到原始的id,你可以将它转换回字节,并使用utf8编码获取string。

请参阅Unicode和ISAPI筛选器

ISAPIfilter是一个ANSI API – 您可以使用API​​获取/设置的所有值必须是ANSI。 是的,我知道这是令人震惊的; 毕竟,这是2006年,现在的一切都在Unicode …但请记住,这个API起源于十多年前,几乎任何东西都是32位,更不用说Unicode了。 另外,请记住,ISAPI直接操作的HTTP协议是ANSI而不是Unicode。

编辑:既然你提到它可以与大多数其他字符,所以我假设IIS有一些编码检测机制,在这种情况下失败。 作为一个解决方法,虽然你可以用这个字符作为你的ID的前缀,然后你可以很容易地检测到问题是否发生(如果这个字符丢失)。 不是一个非常理想的解决scheme,但它会工作。 然后,您可以在ASP.NET MVC中编写自定义模型联编程序和包装类,以使您的消耗代码更清洁。

一次又一次,url本身不是UTF-8。 他们在ANSI代码页。 这有利于他们经常用来select服务器文件系统中的path名。 在古代,IE浏览器可以select是否要发送UTF-8 URL。

也许埋在IISconfiguration的大肠里,有一个地方可以指定URL编码,也许没有。

最终,为了解决这个问题,我不得不使用request.ServerVariables["HTTP_URL"]和一些手动parsing,以及一些error handling回退(另外补偿Uri一些相关故障)。 不是很好,但只影响less数尴尬的请求。