.Net multipart/form-data form enctype和UTF-8"special"characters => (MVC w/HttpPostedFileBase)

Dud*_*000 5 .net asp.net-mvc file-upload utf-8 httppostedfilebase

目标:

将带有UTF-8字符的CSV文件上传/发布到MVC操作,读取数据并将其粘贴到数据库表中.

问题:

只有纯文本字符才能通过.像á这样的UTF-8"特殊"字符没有正确传递,在代码和数据库中它们呈现为此字符=> .

更多:

我确信这不是我的C#代码的问题,尽管我已经包含了下面的重要部分.

我认为问题是上传的文件是以纯文本或"纯文本"MIME类型编码的,但我可以通过将文件扩展名更改为.html来更改它

摘要:

如何获得一个enctype属性设置为"multipart/form-data"的表单,以正确解释已发布文件中的UTF-8字符?

研究:

从我的研究来看,这似乎是一个普遍的问题,没有一个共同和明确的解决方案

我发现了比.Net更多的java和PHP解决方案.


  • csvFile变量的类型为HttpPostedFileBase

  • 这是MVC动作签名

[HttpPost]

public ActionResult LoadFromCsv(HttpPostedFileBase csvFile)


我试过的事情:

1)

using (Stream inputStream = csvFile.InputStream)
{
    byte[] bytes = ReadFully(inputStream);
    string bytesConverted = new UTF8Encoding().GetString(bytes);
}
Run Code Online (Sandbox Code Playgroud)

2)

using (Stream inputStream = csvFile.InputStream)
{
    using (StreamReader readStream = new StreamReader(inputStream, Encoding.UTF8, true))
    {
        while (!readStream.EndOfStream)
        {
            string csvLine = readStream.ReadLine();
            // string csvLine = new UTF8Encoding().GetString(new UTF8Encoding().GetBytes(readStream.ReadLine())); // stupid... this can not be the way!
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

3)

<form method="post" enctype="multipart/form-data" accept-charset="UTF-8">
Run Code Online (Sandbox Code Playgroud)

4)

<input type="file" id="csvFile" name="csvFile" accept="UTF-8" />

<input type="file" id="csvFile" name="csvFile" accept="text/html" />
Run Code Online (Sandbox Code Playgroud)

5)

当文件具有.txt扩展名时,HttpPostedFileBase的ContentType属性为"text/plain"

当我将文件扩展名从.txt更改为.csv时,HttpPostedFileBase的ContentType属性为"application/vnd.ms-excel"

当我将文件扩展名更改为.html时,HttpPostedFileBase的ContentType属性为"text/html" - 我认为这将成为赢家,但事实并非如此.


在我的灵魂中,我不得不相信这个问题有一个简单的解决方案.让我感到惊讶的是,我无法自己解决这个问题,在文件中上传UTF-8字符是一项常见任务!我为什么在这里失败?!?!

也许我必须在IIS中为网站调整mime类型?

也许我需要不同的DOCTYPE/html标签/元标签?


@Gabe -

这是我的帖子在小提琴手中的样子.这真的很有趣,因为 显然是白天,就在后期值.

http://localhost/AwesomeGeography/GeoBytesCities/LoadFromCsv?adsf HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://localhost/AwesomeGeography/GeoBytesCities/LoadFromCsv?adsf
Content-Type: multipart/form-data; boundary=---------------------------199122566726299
Content-Length: 354

-----------------------------199122566726299
Content-Disposition: form-data; name="csvFile"; filename="cities_test.html"
Content-Type: text/html

"CityId","CountryID","RegionID","City","Latitude","Longitude","TimeZone","DmaId","Code"
3344,10,1063,"Luj?n de Cuyo","-33.05","-68.867","-03:00",0,"LDCU"
-----------------------------199122566726299--
Run Code Online (Sandbox Code Playgroud)

Ale*_*imp 3

根据给出的信息,我猜测问题在于文件编码本身 - 而不是您的代码。

\n\n

我进行了一个简单的测试来证明这一点:

\n\n
    \n
  1. 我从 Excel 导出了一个包含特殊字符的简单 csv 文件。

  2. \n
  3. 然后,我通过以下表单和操作方法上传了它。

  4. \n
\n\n

形式

\n\n
<form method="post" action="@Url.Action("UploadFile", "Home")" enctype="multipart/form-data">\n    <input type="file" id="file" name="file" />\n    <input type="submit" />\n</form>\n
Run Code Online (Sandbox Code Playgroud)\n\n

动作方法

\n\n
[HttpPost]\npublic ActionResult UploadFile(HttpPostedFileBase file)\n{\n    using (StreamReader reader = new StreamReader(file.InputStream, System.Text.Encoding.UTF8))\n    {\n        string text = reader.ReadToEnd();\n    }\n\n    return RedirectToAction("Index");\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

在这种情况下,我遇到了与您相同的问题 - 特殊字符被替换为 \xef\xbf\xbd。

\n\n

我在记事本中打开该文件,特殊字符在那里正确显示,所以看起来这不可能是文件问题,但是当我打开“另存为”对话框时,所选的编码是“ANSI”。我将其切换为 UTF-8 并保存,通过上传器运行,一切正常。

\n