如何访问 HttpClient 响应中的 Content-Disposition 标头

发布于 2025-01-19 03:33:01 字数 1630 浏览 0 评论 0原文

我想从服务器下载文件,然后将其保存在服务器建议的文件名中(使用Content-Disposition标头)。

我正在使用httpclient下载文件。

问题在于,我无法获得标头的值,尽管.contains(“ content-disposition”)确认其存在。而且没有错误,只有.contentDisposition为null。

        public async Task DownloadFile(Uri url, string destination) {
            using (HttpClient client = new HttpClient()) {
                client.DefaultRequestHeaders.Add("Authorization", APIKey);
                HttpResponseMessage result = await client.GetAsync(url);
                if (result.StatusCode == HttpStatusCode.NoContent) {
                    return;
                }
                if (result.StatusCode != HttpStatusCode.OK) {
                    throw new Exception("Request from " + url + " returned " + result.StatusCode);
                }

                if (!result.Content.Headers.Contains("Content-Disposition")) {
                    throw new Exception("Request from " + url + " contains no content disposition header.");
                }
                ContentDispositionHeaderValue cd = result.Content.Headers.ContentDisposition;
                if (cd == null) {
                    throw new Exception("Content disposition header is null. headers = " + result.Content.Headers);
                }

                var filename = cd.FileName;
                .
                .
                .
            }
        }

由此产生的例外是: 内容处置标头为空。 [...]处置:文本/CSV; filename = filename.csv [...]

为什么.contentDisposition null,即使.contains(“ content-disposition”)是真的吗?

请注意,这是一项Windows服务,使调试非常糟糕。

I want to download a file from a server and save it with the filename suggested by the server (using Content-Disposition header).

I am using HttpClient to download the file.

The problem is that I cannot get the value of the header, although .Contains("Content-Disposition") confirms that it exists. And there is no error, just the .ContentDisposition is null.

        public async Task DownloadFile(Uri url, string destination) {
            using (HttpClient client = new HttpClient()) {
                client.DefaultRequestHeaders.Add("Authorization", APIKey);
                HttpResponseMessage result = await client.GetAsync(url);
                if (result.StatusCode == HttpStatusCode.NoContent) {
                    return;
                }
                if (result.StatusCode != HttpStatusCode.OK) {
                    throw new Exception("Request from " + url + " returned " + result.StatusCode);
                }

                if (!result.Content.Headers.Contains("Content-Disposition")) {
                    throw new Exception("Request from " + url + " contains no content disposition header.");
                }
                ContentDispositionHeaderValue cd = result.Content.Headers.ContentDisposition;
                if (cd == null) {
                    throw new Exception("Content disposition header is null. headers = " + result.Content.Headers);
                }

                var filename = cd.FileName;
                .
                .
                .
            }
        }

And the resulting exception is:
Content disposition header is null. [...] Disposition: text/csv; filename=filename.csv [...]

Why is the .ContentDisposition null, even though .Contains("Content-Disposition") is true?

Note that this is a Windows service, making debugging quite a bad experience.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

暮倦 2025-01-26 03:33:01

因此,正如@HereticMonkey建议的那样,我使用result.content.headers.getValues(“ content-disposition”)获得了值。那让我获得了字符串表示。当我尝试将其转换为contentDispositionheadervalue时,我得到了一个formatexception。根据相关的RFC,我不知道为什么要正确格式化标题:content-disposition:attactment;文件名= 1282661008.CSV。例外本身不会对我解释太多。

我不得不使用Regex自己对其进行解析:

if (!result.Content.Headers.Contains("Content-Disposition")) {
    throw new Exception("Request from " + url + " contains no content disposition header.");
}
string[] cdarray = result.Content.Headers.GetValues("Content-Disposition").ToArray();
if (cdarray.Length != 1) {
    throw new Exception("There is not exactly one Content-Disposition header. There is/are " + cdarray.Length);
}

GroupCollection groups = Regex.Match(cdarray[0], @"filename=""?([\w\.]*)""?").Groups;
if (groups.Count != 2) {
    throw new Exception("Failed to parse the Content-Disposition header " + cdarray[0]);
}
var filename = groups[1].Value;

我觉得我没有进来的东西。为什么创建contentDispositionheadervalue更具描述性的异常呢?

So, as @hereticmonkey suggested, I got the value using result.Content.Headers.GetValues("Content-Disposition"). That got me the string representation. When I tried to convert it to ContentDispositionHeaderValue, I got a FormatException. I have no idea why, as the header should be properly formatted, according to the relevant RFC: Content-Disposition: attachment; filename=1282661008.csv. The exception itself won't explain much to me.

I had to parse it myself using regex:

if (!result.Content.Headers.Contains("Content-Disposition")) {
    throw new Exception("Request from " + url + " contains no content disposition header.");
}
string[] cdarray = result.Content.Headers.GetValues("Content-Disposition").ToArray();
if (cdarray.Length != 1) {
    throw new Exception("There is not exactly one Content-Disposition header. There is/are " + cdarray.Length);
}

GroupCollection groups = Regex.Match(cdarray[0], @"filename=""?([\w\.]*)""?").Groups;
if (groups.Count != 2) {
    throw new Exception("Failed to parse the Content-Disposition header " + cdarray[0]);
}
var filename = groups[1].Value;

I feel like there is something I don't get in .NET: Why there was no exception thrown when it failed to parse when accessing through .ContentDisposition? Why isn't the exception thrown while creating ContentDispositionHeaderValue more descriptive?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文