C# 如何在S3'中使用unicode字符;s响应内容处置头?

C# 如何在S3'中使用unicode字符;s响应内容处置头?,c#,amazon-web-services,amazon-s3,C#,Amazon Web Services,Amazon S3,我们使用此代码生成请求并设置下载文件名: var request = new GetPreSignedUrlRequest() .WithBucketName(S3BucketName) .WithExpires(requestExpirationTime) .WithKey(file.S3Key) .WithResponseHeaderOverrides( new ResponseHeaderOverrides() .Wi

我们使用此代码生成请求并设置下载文件名:

var request = new GetPreSignedUrlRequest()
    .WithBucketName(S3BucketName)
    .WithExpires(requestExpirationTime)
    .WithKey(file.S3Key)
    .WithResponseHeaderOverrides(
        new ResponseHeaderOverrides()
            .WithContentDisposition("attachment; filename=\"Unicode FileName ᗩ Test.txt\""));
/s3path?AWSAccessKeyId=xxxx&Expires=1377199946&response-content-disposition=attachment%3B%20filename%3D"Unicode%20FileName%20ᗩ%20Test.txt"&Signature=xxxxx
<Error>
    <Code>InvalidArgument</Code>
    <Message>
        Header value cannot be represented using ISO-8859-1.
    </Message>
    <ArgumentValue>attachment; filename="Unicode ᗩ filename.txt"</ArgumentValue>
    <ArgumentName>response-content-disposition</ArgumentName>
    <RequestId>368BD60502854514</RequestId>
    <HostId>
        BiUUYp4d9iXfK68jKVxWZEp25m5je166M0ZY1VmoPk9pN9A69HLHcff6WIVLWk1B
    </HostId>
</Error>
这将生成以下链接:

var request = new GetPreSignedUrlRequest()
    .WithBucketName(S3BucketName)
    .WithExpires(requestExpirationTime)
    .WithKey(file.S3Key)
    .WithResponseHeaderOverrides(
        new ResponseHeaderOverrides()
            .WithContentDisposition("attachment; filename=\"Unicode FileName ᗩ Test.txt\""));
/s3path?AWSAccessKeyId=xxxx&Expires=1377199946&response-content-disposition=attachment%3B%20filename%3D"Unicode%20FileName%20ᗩ%20Test.txt"&Signature=xxxxx
<Error>
    <Code>InvalidArgument</Code>
    <Message>
        Header value cannot be represented using ISO-8859-1.
    </Message>
    <ArgumentValue>attachment; filename="Unicode ᗩ filename.txt"</ArgumentValue>
    <ArgumentName>response-content-disposition</ArgumentName>
    <RequestId>368BD60502854514</RequestId>
    <HostId>
        BiUUYp4d9iXfK68jKVxWZEp25m5je166M0ZY1VmoPk9pN9A69HLHcff6WIVLWk1B
    </HostId>
</Error>
产生此错误:

var request = new GetPreSignedUrlRequest()
    .WithBucketName(S3BucketName)
    .WithExpires(requestExpirationTime)
    .WithKey(file.S3Key)
    .WithResponseHeaderOverrides(
        new ResponseHeaderOverrides()
            .WithContentDisposition("attachment; filename=\"Unicode FileName ᗩ Test.txt\""));
/s3path?AWSAccessKeyId=xxxx&Expires=1377199946&response-content-disposition=attachment%3B%20filename%3D"Unicode%20FileName%20ᗩ%20Test.txt"&Signature=xxxxx
<Error>
    <Code>InvalidArgument</Code>
    <Message>
        Header value cannot be represented using ISO-8859-1.
    </Message>
    <ArgumentValue>attachment; filename="Unicode ᗩ filename.txt"</ArgumentValue>
    <ArgumentName>response-content-disposition</ArgumentName>
    <RequestId>368BD60502854514</RequestId>
    <HostId>
        BiUUYp4d9iXfK68jKVxWZEp25m5je166M0ZY1VmoPk9pN9A69HLHcff6WIVLWk1B
    </HostId>
</Error>

如何在响应内容处置标题中使用非ISO-8859-1字符,如unicode?

我遇到了这个问题,通过正确编码unicode字符串解决了这个问题

我在蟒蛇之地:

然后,使用此编码字符串作为响应内容处置标头的值

在Java中,我相信您可以通过以下方式获得相同的结果:

URLEncoder.encode(original_string, "UTF-8")
希望这对其他人有所帮助

如所述,在内容配置中没有可互操作的编码非ASCII名称的方法。浏览器兼容性一团糟。

我们最终的做法是将所有非ISO-8859-1字符替换为“-”。代码如下:

private static readonly Encoding ContentDispositionHeaderEncoding = Encoding.GetEncoding("ISO-8859-1");

public static string GetWebSafeFileName(string fileName)
{
    // We need to convert the file name to ISO-8859-1 due to browser compatibility problems with the Content-Disposition Header (see: https://stackoverflow.com/a/216777/1038611)
    var webSafeFileName = Encoding.Convert(Encoding.Unicode, ContentDispositionHeaderEncoding, Encoding.Unicode.GetBytes(fileName));

    // Furthermore, any characters not supported by ISO-8859-1 will be replaced by « ? », which is not an acceptable file name character. So we replace these as well.
    return ContentDispositionHeaderEncoding.GetString(webSafeFileName).Replace('?', '-');
}

按照Alex Couper的回答,我在.net中找到了一种方法,通过调用HttpEncoder中的内部方法,只对非ascii字符进行编码

不建议调用内部函数,因为它们可能会在未来版本的框架中发生更改!此外,这不会在上述所有浏览器中都起作用。我把这个留在这里,以防有人绝对需要这样做。

var type = typeof(System.Web.Util.HttpEncoder);
var methodInfo = type.GetMethod("UrlEncodeNonAscii", BindingFlags.NonPublic | BindingFlags.Instance, null, new [] { typeof(string), typeof(Encoding) }, null);
object[] parameters = {fileName, Encoding.UTF8};

var encoder = new System.Web.Util.HttpEncoder();

var encodedFileName = (string) methodInfo.Invoke(encoder, parameters);

AWS论坛线程:我在.net中找到了这个函数:System.Web.HttpUtility.UrlEncode(文件名,Encoding.UTF8)。问题是它还将用+字符替换空格,并且它还将编码大多数非字母字符,例如',这使得下载文件的名称看起来很混乱。我发现这项工作的完美功能,但遗憾的是它被标记为内部(在HttpEncoder.cs中),因此如果没有一些技巧,它无法直接使用Helper只对非ASCII url字符进行编码内部字符串URLENCENCONONASCII(字符串str,编码e)对java尝试了这种方法,但仍然存在相同的问题
附件;文件名*=UTF-8“”犬.jpg
噢,哇,微软已经完成了这个功能,并且正在隐藏它!如果有人能够在vb.net中使用源CS文件中的原始函数,那么就可以了!我不知道如何转换“IntToHex((b>>4)&0xf);”部分!(在线转换器也不能)这里是VB.net中的部分:IntToHex((b>>4)和&Hf)