7

目标:

将带有 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);
}

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!
        }
    }
}

3)

<form method="post" enctype="multipart/form-data" accept-charset="UTF-8">

4)

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

<input type="file" id="csvFile" name="csvFile" accept="text/html" />

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 标签 / meta 标签?


@加布-

这是我的帖子在提琴手中的样子。这真的很有趣,因为 � 很简单,就在 post 值中。

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--
4

2 回答 2

4

我有同样的问题,你可以使用

StreamReader reader = new StreamReader(archivo_origen.InputStream, Encoding.GetEncoding("iso-8859-1"));

它有效,“iso-8859-1”适用于拉丁语衍生语言,如西班牙语、aleman、frances

于 2012-11-20T19:30:39.130 回答
3

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

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

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

  2. 然后,我通过下面的表单和操作方法上传了它。

形式

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

动作方法

[HttpPost]
public ActionResult UploadFile(HttpPostedFileBase file)
{
    using (StreamReader reader = new StreamReader(file.InputStream, System.Text.Encoding.UTF8))
    {
        string text = reader.ReadToEnd();
    }

    return RedirectToAction("Index");
}

在这种情况下,我遇到了和你一样的问题 - 特殊字符被替换为�。

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

于 2012-09-23T17:28:45.387 回答