asp.net mvc文件下载--System.FormatException:在邮件头中找到了无效字符

时间:2010-01-13 14:49:13

标签: c# asp.net-mvc

我们的网站有几种不同语言的文件 - 法语,西班牙语,葡萄牙语和英语。当用户上传包含特殊字符(如ó或ç或ã等)的文件时,我在MVC中返回File(data, "application/octet-stream", name);时会收到错误消息,我得到异常:

System.FormatException: An invalid character was found in the mail header.

我在MSDN中发现了一篇文章,展示了如何将mailmessage设置为UTF-8编码以避免这种情况。但是我不知道在使用MVC文件actionresult时如何对文件名进行UTF-8编码。我在网上找到一篇文章,以UTF-8编码一个字符串,但是当我尝试使用它时,我得到一个垃圾名称,所以我想我不明白UTF-8编码应该对字符串做什么。以下是此博客文章中的示例代码:An invalid character was found in the mail header

 public static string GetCleanedFileName(string s)
    {

        char[] chars = s.ToCharArray();

        var sb = new StringBuilder();

        for (int index = 0; index < chars.Length; index++)
        {
            string encodedString = EncodeChar(chars[index]);
            sb.Append(encodedString);
        }
        return sb.ToString();
    }


    private static string EncodeChar(char chr)
    {

        var encoding = new UTF8Encoding();

        var sb = new StringBuilder();

        byte[] bytes = encoding.GetBytes(chr.ToString());

        for (int index = 0; index < bytes.Length; index++)
        {
            sb.AppendFormat("%{0}", Convert.ToString(bytes[index], 16));
        }
        return sb.ToString();
    } 

3 个答案:

答案 0 :(得分:0)

也许尝试使用和转换为utf8的其他函数


//UTF8
        public static string ConvertToUTF8(string inputString)
        {
            string toReturn = "";
            byte[] arr = Encoding.UTF8.GetBytes(inputString);
            for (int i = 0; i < arr.Length; i++)
            {
                toReturn += arr[i].ToString() + " ";
            }

            return toReturn;
        }

        public static string ConvertFromUTF8(string inputString)
        {
            inputString = inputString.Trim();
            string result = "";
            string[] parts = inputString.Split(' ');
            byte[] bytes = new byte[parts.Length];
            for (int i = 0; i < parts.Length; i++)
            {
                if (parts[i] == "")
                {
                    continue;
                }
                try
                {
                    bytes[i] = Convert.ToByte(parts[i]);
                }
                catch (Exception)
                {
                    MessageBox.Show("Input string was not in a correct format.");
                }

            }

            try
            {
                result = Encoding.UTF8.GetString(bytes);
            }
            catch (Exception)
            {
                throw;
            }
            return result;
        }

答案 1 :(得分:0)

我想我已经知道你必须将你的字符串转换为utf-8而不是utf-16 因为我认为utf-8是ascii。

UTF-16表示使用两个字节的每个字符。 UTF-8对ASCII字符使用单字节ASCII字符编码,并使用可变长度编码表示非ASCII字符。请记住,虽然UTF-8可以为西方语言节省空间,这是支持者经常使用的一个参数,但实际上每个字符最多可以使用三个字节用于其他语言。

你写的符号不是ASCII

答案 2 :(得分:-1)

您所指的垃圾字符串是字符的编码版本。您应该只在响应中看到“垃圾”版本。当保存到磁盘时,操作系统应解析编码,并实际显示正确的字符。

什么时候将文件流式传输到客户端,代码看起来像这样:

public ActionResult SaveFile(string fileName)
{
    string fileName = string.Empty; 
    var content=GetContent();
    fileName = CleanFileName(fileName);

    MemoryStream ms = new MemoryStream();
    StreamWriter writer = new StreamWriter(ms, Encoding.UTF8);

    writer.Write(content);
    return File(ms, "text/csv", fileName);
 }

当我运行时尝试保存名为ó or ç or ã的文件时,您会在响应中看到%c3%b3%20%6f%72%20%c3%a7%20%6f%72%20%c3%a3

但是,当文件保存到磁盘时,操作系统会显示ó or ç or ã