2016-07-07 10 views
3

初めての質問を失敗したので、私はそれが間違ってやっているなら、私に知らせて...のC#MVC PDFのダウンロードは、Androidクロムにここ

私のC#のMVC5アプリは、ユーザーがPDFファイルをダウンロードすることができます。それは私のアンドロイド携帯電話を除いて素晴らしい作品です。私はクロムを使用しており、OSにPDFを処理させています。 GoogleドライブアプリのPDFビューアのビルドを使用しているようです。

ファイルへの直接リンクを使用すると正常に動作しますが、コントローラのアクションでダウンロードすると「ファイルが無効です」というエラーが発生します。私はこの質問のテストケースに単純化しました。

public ActionResult IndirectTestFile() 
{ 
string filename = "document.pdf"; 

var disposition = new System.Net.Mime.ContentDisposition("inline") { FileName = filename }; 
Response.AppendHeader("Content-Disposition", disposition.ToString()); 

string serverFilename = Server.MapPath("~/files/direct/" + filename); 
return File(serverFilename, "application/pdf"); 
} 

と私のHTML::

//This fails: 
<a href="/report/indirectTestFile">Indirect link to file</a> 

//This works: 
<a href="/Files/direct/Document.pdf">Direct link to file</a> 

すると、私はこれらのリクエストのヘッダーを取得するには、Windows(デスクトップ)Chromeを使用してい

だからここに私のアクションメソッドです。

ここに直接リンク用応答ヘッダだ:

HTTP/1.1 200 OK 
Content-Type: application/pdf 
Last-Modified: Thu, 07 Jul 2016 11:46:47 GMT 
Accept-Ranges: bytes 
ETag: "b8a3dd3d45d8d11:0" 
Server: Microsoft-IIS/10.0 
X-Powered-By: ASP.NET 
Date: Thu, 07 Jul 2016 12:33:05 GMT 
Content-Length: 51793 

そしてMVCのアクションへのリンクのためのレスポンスヘッダ:

HTTP/1.1 200 OK 
Cache-Control: private, s-maxage=0 
Content-Type: application/pdf 
Server: Microsoft-IIS/10.0 
Content-Disposition: inline; filename=document.pdf 
X-AspNet-Version: 4.0.30319 
X-Powered-By: ASP.NET 
Date: Thu, 07 Jul 2016 12:34:09 GMT 
Content-Length: 51793 

私はそこに任意の大きな違いは表示されませんが、1であります確実に動作し、他方は確実に故障する。

これは破損したダウンロードではありません。 Windows上で「悪い」PDFをダウンロードしてアンドロイド電話にコピーすると、同じビューアが表示されます。

誰でもこれを見る前に?助けてくれてありがとう。

答えて

1

私はこの問題を解決していないが、私は、原因だった正確に何を見つけるんでした。 Googleのログを見ると、Googleドライブ/ docsアプリがブラウザの代わりにダウンロードを処理しているようです。リクエストは、ブラウザとは別のユーザーエージェントを介して行われます。

つまり、別のセッションで発生します。そのセッションはWebサイトにログインしていないので、PDFをダウンロードする代わりに、ログインページにリダイレクトされてダウンロードされ、有効なPDFファイルではないと訴えます!だからそれが起こるのです。

私は、コントローラからの認証を削除することで、要求がリダイレクトされないようにテストしました。pdfがダウンロードされ、okと表示されます。

クロムが直接ダウンロード自体を処理する理由はわかりませんが、コントローラのリンクをGoogleアプリに渡します。私は、両方のリクエストが同じヘッダを返すようにサーバを変更しました。そのため、私はクロムがどのようにして2つの違いを見分けることができないのか分かりませんが、違いはあります。

この問題を回避するために私のアプリを理解するか再構成する必要がありますが、それは別の質問のためかもしれません。

フランのアイデアのおかげで。

更新: 私は(とても悲しい、それは...ほんの数週間前だった)これに対する厳密解を覚えていませんが、私は私のコントローラのアクションにリダイレクトされたため、それがあったと思います。例えば私は、これはPDFファイルを作成し、それをユーザーに返すアクションにリダイレクトします。このようなアクション(簡体字)

public ActionResult MakePDF(string id) 
    { 
     // code to create the file removed for clarity. 
     return RedirectToAction("IndirectTestFile"); 
    } 

を持っているでしょう。

だから私はこの

public ActionResult MakePDF(string id) 
    { 
     // code to create the file removed for clarity. 
     return IndirectTestFile(); 
    } 

のようなリダイレクトを切り取り、それが解決策になるようだ - 私はとにかく、このメソッドを使用していますし、それは私のために働いています。

+0

私はこの同じ正確な問題を抱えています。あなたが何かを見つけたら更新を投稿しますか?私は研究を続けるつもりです。 – Danation

+0

これはContent-Dispositionヘッダーが原因であるようです。私はそれを働かせるために様々なことを試みたが、私は多くの運がなかった。それをインライン化しようとしないと、Chromeは単にそれをダウンロードします。 – Danation

+0

Content-Dispositionで見た唯一の違いは、添付ファイルに設定した場合、ダウンロードするようにChromeに指示しているため、ダウンロードしてGoogleドライブアプリに渡す必要はありません。 – EamonnM

0

私はPDFファイルを書くとき、私は、ファイルのバイト数を渡し、PdfResultを使用することができ、コントローラのアクションを変更しますカスタムPdfResult

public class PdfResult : FileResult 
{ 
    private const String DefaultFileName = "file.pdf"; 
    private readonly Byte[] _byteArray; 

    public PdfResult(Byte[] byteArray, String fileName = DefaultFileName) 
     : base(MediaTypeNames.Application.Pdf) 
    { 
     _byteArray = byteArray; 
     FileDownloadName = fileName; 
    } 

    protected override void WriteFile(HttpResponseBase response) { response.BinaryWrite(_byteArray); } 
} 

を使用しています。 File.ReadAllBytesを使用してバイトを取得できます。ブラウザがファイルを直接読み込んで仕事をしているので、

public ActionResult IndirectTestFile() 
{ 
string filename = "document.pdf"; 

var fileBytes = File.ReadAllBytes(Server.MapPath("~/files/direct/" + filename)); 
return new PdfResult(fileBytes, filename); 
} 

あなたは、第2のリンク

<a href="/Files/direct/Document.pdf">Direct link to file</a> 

で動作します。将来サーチャーのために

+0

こんにちはフラン、私はあなたのコードを試しましたが、それはコンテンツの処分を使用するように動作するかどうかを知ることができません:ダウンロードを強制する添付ファイル。 ダウンロードは正常に動作し、表示できますが、インラインでは表示できません。これを添付ファイルではなくインラインにすることができますか? ファイルをストリームに読み込む別の方法を除いて、ここで大きな違いがあるかどうかはわかりません。 – EamonnM

+0

あなたはブラウザが2番目のリンクを直接ダウンロードしていると言います - 私が理解するように、ブラウザはまったく同じ方法で両方のリンクをダウンロードしています。ブラウザが両方をダウンロードしているか、PDFビューアがダウンロードされています。ブラウザがダウンロードするのは意味がありませんが、PDFビューアはもう一方をダウンロードしています。たぶん私は間違っています? – EamonnM

+0

私はあなたの最初のリンクが真中にasp.net mvcを置くことを意味しました。正確なファイルへのhrefを持つアンカータグはコントローラアクションを経由しません。したがって、タグは解釈されますが、ブラウザはaタグを解釈します。 – Fran

関連する問題