我需要允许用户从我们的服务器下载文件,并且我想通过ASP.NET MVC 5控制器操作来提供这些文件。我的行为如下:
public FileContentResult Download(int fileId)
{
var myContent = GetContentForFile(fileId);
var myFileMeta = GetFileMeta(fileId);
if (myContent == null || myFileMeta == null)
throw new FriendlyException("The file or its associated data could not be found.");
return File(myContent.Content, myContent.MediaType, myFileMeta.FileName);
}
以上就像我能得到的一样简单,它在PC和iPhone上运行良好,但在Android上运行不正常。使用Fiddler,当我尝试下载我的一个文件时,我可以看到以下响应头 - 在这种情况下是一个名为“1447114384146-643143584.jpg”的JPG文件:
HTTP/1.1 200 OK
Cache-Control: private, s-maxage=0
Content-Type: image/jpeg
Server: Microsoft-IIS/8.5
X-AspNetMvc-Version: 5.2
Content-Disposition: attachment; filename=1447114384146-643143584.jpg
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 12 Nov 2015 23:09:00 GMT
Content-Length: 1682868
请注意,我没有任何可靠的方法来了解正确的MIME类型 - 这是一个问题,是否可以解释为什么文件没有在Android中下载?
为了澄清一下,当我尝试使用Android从数据库下载任何文件时,我收到一个Toast通知告诉我“Download started”,但随后下载在队列中停留了一段时间0%才最终改为“失败”。
我尝试了什么
我已经尝试过人们在类似问题中提出的所有方式,其中大多数问题与content-disposition
标题或content-type
标题有关。我已尝试为每个文件强制content-type
标题为application/octet-stream
,我已尝试为特定文件发送正确的content-type
标头。我尝试过手动发送content-disposition
标头。我已经尝试将文件扩展名强制为大写。
以上都没有奏效,事实上它们都没有对这个问题产生任何影响,无论是更好还是更糟。我很惊讶这很难 - 我觉得我一定会错过一些明显的东西吗?
其他信息
更新
阅读此博客文章后:http://www.digiblog.de/2011/04/android-and-the-download-file-headers/我尝试按照建议操作并完全按照建议设置标题:
HTTP/1.1 200 OK
Cache-Control: private, s-maxage=0
Content-Type: application/octet-stream
Server: Microsoft-IIS/8.5
X-AspNetMvc-Version: 5.2
Content-Disposition: attachment; filename="1447114384146-643143584.JPG"
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 12 Nov 2015 23:42:18 GMT
Content-Length: 1682868
同样,这对问题没有任何影响。
进一步更新
我已经能够在Marshmallow(Android v6.0)设备上进行测试,下载工作正常。这似乎是一个Marshmallow之前的问题。
答案 0 :(得分:2)
可悲的是,这是由我的环境非常具体的事情引起的,但我想在这里给出答案,万一其他人偶然遇到同样的问题。
事实证明,Android下载管理器不喜欢域名中的下划线,而我们的本地域名地址中有下划线。我使用了服务器的IP地址,一切都按预期工作。
例如:ASCII
无效。这:http://www.my_domain.com.au/file.png
确实有用。
答案 1 :(得分:0)
免责声明:我没有足够的代表添加评论,因此我不得不在此发表评论。
作为一种排除设备设置问题的方法是使用Xamarin + RestSharp编写一个小型Android应用程序,它只会点击你的下载URL,看看是否有效。如果确实如此,则有助于将手指指向Chrome本身。如果它没有,那么至少你可以运行附带调试器的应用程序,以便更好地了解另一端发生的事情。
https://github.com/restsharp/RestSharp
UPDATE: Fiddler在调用本地计算机提供的测试时看到的响应标头
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: application/octet-stream
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Content-Disposition: attachment; filename=profile.jpg
Date: Fri, 13 Nov 2015 02:09:23 GMT
Content-Length: 218143
更新:以下是传入请求服务器变量
ALL_HTTP=HTTP_CACHE_CONTROL:max-age=0
HTTP_CONNECTION:keep-alive
HTTP_ACCEPT:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
HTTP_ACCEPT_ENCODING:gzip, deflate, sdch
HTTP_ACCEPT_LANGUAGE:en-US,en;q=0.8
HTTP_COOKIE:_ga=GA1.1.420021277.1447377172
HTTP_HOST:192.168.1.2
HTTP_USER_AGENT:Mozilla/5.0 (Linux; Android 5.0.2; HTC One Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36
HTTP_UPGRADE_INSECURE_REQUESTS:1
HTTP_DNT:1
ALL_RAW=Cache-Control: max-age=0
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: _ga=GA1.1.420021277.1447377172
Host: 192.168.1.2
User-Agent: Mozilla/5.0 (Linux; Android 5.0.2; HTC One Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36
Upgrade-Insecure-Requests: 1
DNT: 1
APPL_MD_PATH=/LM/W3SVC/2/ROOT
APPL_PHYSICAL_PATH=C:\development\rumble-strip\projects\net-framework\RumbleStrip.Website\
AUTH_TYPE=
AUTH_USER=
AUTH_PASSWORD=
LOGON_USER=
REMOTE_USER=
CERT_COOKIE=
CERT_FLAGS=
CERT_ISSUER=
CERT_KEYSIZE=
CERT_SECRETKEYSIZE=
CERT_SERIALNUMBER=
CERT_SERVER_ISSUER=
CERT_SERVER_SUBJECT=
CERT_SUBJECT=
CONTENT_LENGTH=0
CONTENT_TYPE=
GATEWAY_INTERFACE=CGI/1.1
HTTPS=off
HTTPS_KEYSIZE=
HTTPS_SECRETKEYSIZE=
HTTPS_SERVER_ISSUER=
HTTPS_SERVER_SUBJECT=
INSTANCE_ID=2
INSTANCE_META_PATH=/LM/W3SVC/2
LOCAL_ADDR=192.168.1.2
PATH_INFO=/
PATH_TRANSLATED=C:\development\rumble-strip\projects\net-framework\RumbleStrip.Website
QUERY_STRING=&REMOTE_ADDR=192.168.1.5&REMOTE_HOST=192.168.1.5
REMOTE_PORT=54748
REQUEST_METHOD=GET
SCRIPT_NAME=/
SERVER_NAME=192.168.1.2
SERVER_PORT=80
SERVER_PORT_SECURE=0
SERVER_PROTOCOL=HTTP/1.1
SERVER_SOFTWARE=Microsoft-IIS/10.0
URL=/
HTTP_CACHE_CONTROL=max-age=0
HTTP_CONNECTION=keep-alive
HTTP_ACCEPT=text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
HTTP_ACCEPT_ENCODING=gzip, deflate, sdch
HTTP_ACCEPT_LANGUAGE=en-US,en;q=0.8
HTTP_COOKIE=_ga=GA1.1.420021277.1447377172
HTTP_HOST=192.168.1.2
HTTP_USER_AGENT=Mozilla/5.0 (Linux; Android 5.0.2; HTC One Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36
HTTP_UPGRADE_INSECURE_REQUESTS=1
HTTP_DNT=1
IS_LOGIN_PAGE=1