Is IIS performing an illegal character substitution? If so, how to stop it?

后端 未结 3 1064
执笔经年
执笔经年 2020-12-14 15:14

Context: ASP.NET MVC running in IIS, with a a UTF-8 %-encoded URL.

Using the standard project template, and a test-action in HomeController like:

<
相关标签:
3条回答
  • 2020-12-14 15:22

    Once Upon A Time, URLs themselves were not in UTF-8. They were in the ANSI code page. This facilitates the fact that they often are used to select, well, pathnames in the server's file system. In ancient times, IE had an option to tell whether you wanted to send UTF-8 URLs or not.

    Perhaps buried in the bowels of the IIS config there is a place to specify the URL encoding, and perhaps not.

    0 讨论(0)
  • 2020-12-14 15:38
    id = Encoding.UTF8.GetString(Encoding.Default.GetBytes(id));
    

    This will give you your original id. IIS uses Default (ANSI) encoding for path characters. Your url encoded string is decoded using that and that is why you're getting a weird thing back.

    To get the original id you can convert it back to bytes and get the string using utf8 encoding.

    See Unicode and ISAPI Filters

    ISAPI Filter is an ANSI API - all values you can get/set using the API must be ANSI. Yes, I know this is shocking; after all, it is 2006 and everything nowadays are in Unicode... but remember that this API originated more than a decade ago when barely anything was 32bit, much less Unicode. Also, remember that the HTTP protocol which ISAPI directly manipulates is in ANSI and not Unicode.

    EDIT: Since you mentioned that it works with most other characters so I'm assuming that IIS has some sort of encoding detection mechanism which is failing in this case. As a workaround though you can prefix your id with this char and then you can easily detect if the problem occurred (if this char is missing). Not a very ideal solution but it will work. You can then write your custom model binder and a wrapper class in ASP.NET MVC to make your consumption code cleaner.

    0 讨论(0)
  • 2020-12-14 15:44

    Ultimately, to get around this, I had to use request.ServerVariables["HTTP_URL"] and some manual parsing, with a bunch of error-handling fallbacks (additionally compensating for some related glitches in Uri). Not great, but only affects a tiny minority of awkward requests.

    0 讨论(0)
提交回复
热议问题