Created
January 21, 2021 15:05
-
-
Save jzwang-dev/886d631f13ed050fd629f6fb53abc952 to your computer and use it in GitHub Desktop.
ASP.NET下載檔案包含中文檔名Header處理
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 下載檔案包含中文檔名Header處理 | |
// Wang, Jian-Zhong | |
using System.Text; | |
namespace JZLib | |
{ | |
public static class HeaderUtil | |
{ | |
private const string HexDigits = "0123456789ABCDEF"; | |
private static void AddByteToStringBuilder(byte b, StringBuilder builder) | |
{ | |
builder.Append('%'); | |
int i = b; | |
AddHexDigitToStringBuilder(i >> 4, builder); | |
AddHexDigitToStringBuilder(i % 16, builder); | |
} | |
private static void AddHexDigitToStringBuilder(int digit, StringBuilder builder) | |
{ | |
builder.Append(HexDigits[digit]); | |
} | |
private static string CreateRfc2231FileName(string filename) | |
{ | |
StringBuilder builder = new StringBuilder(""); | |
byte[] filenameBytes = Encoding.UTF8.GetBytes(filename); | |
foreach (byte b in filenameBytes) | |
{ | |
if (IsByteValidHeaderValueCharacter(b)) | |
{ | |
builder.Append((char)b); | |
} | |
else | |
{ | |
AddByteToStringBuilder(b, builder); | |
} | |
} | |
return builder.ToString(); | |
} | |
/// <summary> | |
/// 取得下載檔案名稱含Unicode字元如中文的Content-Disposition Header值 | |
/// </summary> | |
/// <param name="filename">含Unicdoe字元的檔案名稱</param> | |
/// <param name="inline">true表示以inline的形式呈現於頁面中以瀏覽器預覽,false表示在Header中指定attachment強制瀏覽器下載</param> | |
/// <returns>下載檔案名稱含Unicode字元如中文的Content-Disposition Header值</returns> | |
/// <example> | |
/// Response.AppendHeader("Content-Disposition", JZLib.HeaderUtil.GetUnicodeContentDisposition("測試中文.txt", false)); | |
/// </example> | |
public static string GetUnicodeContentDisposition(string filename, bool inline = true) | |
{ | |
return $"{(inline ? "inline" : "attachment")}; filename*=UTF-8''{CreateRfc2231FileName(filename)}"; | |
} | |
// Application of RFC 2231 Encoding to Hypertext Transfer Protocol (HTTP) Header Fields, sec. 3.2 | |
// http://greenbytes.de/tech/webdav/draft-reschke-rfc2231-in-http-latest.html | |
private static bool IsByteValidHeaderValueCharacter(byte b) | |
{ | |
if ((byte)'0' <= b && b <= (byte)'9') | |
{ | |
return true; // is digit | |
} | |
if ((byte)'a' <= b && b <= (byte)'z') | |
{ | |
return true; // lowercase letter | |
} | |
if ((byte)'A' <= b && b <= (byte)'Z') | |
{ | |
return true; // uppercase letter | |
} | |
switch (b) | |
{ | |
case (byte)'-': | |
case (byte)'.': | |
case (byte)'_': | |
case (byte)'~': | |
case (byte)':': | |
case (byte)'!': | |
case (byte)'$': | |
case (byte)'&': | |
case (byte)'+': | |
return true; | |
} | |
return false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment