ASP.NET使用WebClient下载重定向文件时如何获取目标文件名
解决方案
问题原因
你当前无法获取文件名的核心原因有两个:
WebClient默认开启自动重定向逻辑,不会暴露最终跳转后的请求URI,你能拿到的只有最终200响应的头,而该响应头没有返回Content-Disposition字段携带文件名- 跳转后的文件名就存在于最终请求的URL路径中,只要拿到最终URL即可提取文件名
实现方案
不需要修改任何IIS配置,仅调整客户端代码即可,以下提供两种常用实现方式:
方案1:使用HttpWebRequest(更推荐,灵活度更高)
HttpWebRequest 可以直接返回重定向后的最终响应地址,直接提取路径最后一段作为文件名即可:
' 提前导入所需命名空间:System.IO、System.Net、System.Net.Mime Dim sourceUrl As String = "http://www.URL.com_that_redirects_to_random_file.pfx" Dim finalFileName As String = "" Dim savePath As String = "c:/" ' 创建请求,允许自动跟随重定向 Dim request As HttpWebRequest = WebRequest.Create(sourceUrl) request.AllowAutoRedirect = True request.Method = "GET" Using response As HttpWebResponse = request.GetResponse() ' 拿到最终跳转后的URI Dim finalUri As Uri = response.ResponseUri ' 从URI路径中提取文件名 finalFileName = Path.GetFileName(finalUri.AbsolutePath) ' 可选:优先读取响应头的Content-Disposition文件名(兼容后续对方站点新增该字段的场景) Dim dispositionHeader As String = response.Headers("Content-Disposition") If Not String.IsNullOrEmpty(dispositionHeader) Then Dim disposition As ContentDisposition = New ContentDisposition(dispositionHeader) finalFileName = disposition.FileName End If ' 下载文件到指定路径 Using responseStream As Stream = response.GetResponseStream() Using fileStream As FileStream = New FileStream(Path.Combine(savePath, finalFileName), FileMode.Create) responseStream.CopyTo(fileStream) End Using End Using End Using
方案2:自定义WebClient实现(兼容原有代码写法)
如果要继续用WebClient的语法,可以继承WebClient类暴露最终响应URI:
' 提前导入所需命名空间:System.IO、System.Net ' 自定义WebClient类,添加FinalUri属性保存最终跳转地址 Public Class CustomWebClient Inherits WebClient Public Property FinalUri As Uri Protected Overrides Function GetWebResponse(request As WebRequest) As WebResponse Dim response As WebResponse = MyBase.GetWebResponse(request) FinalUri = response.ResponseUri Return response End Function End Class ' 业务代码调用 Dim sourceUrl As String = "http://www.URL.com_that_redirects_to_random_file.pfx" Dim savePath As String = "c:/" Using client As New CustomWebClient() ' 先发送请求获取响应头,拿到文件名 Dim data As Byte() = client.DownloadData(sourceUrl) Dim finalFileName As String = Path.GetFileName(client.FinalUri.AbsolutePath) ' 保存文件 File.WriteAllBytes(Path.Combine(savePath, finalFileName), data) End Using
注意事项
- 不需要配置任何IIS:该需求仅需要在客户端请求逻辑中调整即可,和你本地的服务端配置无关
- 请求的源地址需要补全
http://或https://前缀,否则会抛出请求格式错误 - 如果最终URL的路径没有显式文件名,才需要对方站点配置IIS添加
Content-Disposition响应头,你已经说明无法修改对方站点逻辑,所以优先使用URL提取的方案即可
内容的提问来源于stack exchange,提问作者Devmyselz
相关产品推荐
相关产品推荐

