1

サードパーティの html から pdf への変換 (DocRaptor) を使用しています。HTML を彼らのサイトに投稿すると、彼らは PDF で応答します。彼らが提供するスターター コードは問題なく動作しますが、ファイルがハードドライブに配置されます。私は彼らのコードを修正して、ブラウザ経由でファイルをダウンロードできるようにしました。したがって、HTTP 応答から得られるデータが適切なデータであると 100% 確信しています。使用可能なファイルに戻すことができないようです。

問題は、responseStream データの処理方法にあると確信しています。Try/Catchに入ると、すべてがうまくいかないようです。私は c# と Web プログラミングに非常に慣れていないので、ここで SO ユーザーからのガイダンスをいただければ幸いです。ありがとう。これが私のコードです。

            string postData = String.Format(PostFormat,
            (string.IsNullOrEmpty(DocumentContent) ? "document_url" : "document_content"),
            HttpUtility.UrlEncode(string.IsNullOrEmpty(DocumentContent) ? DocumentURL : DocumentContent),
            HttpUtility.UrlEncode(Name),
            HttpUtility.UrlEncode(type),
            HttpUtility.UrlEncode(Test.ToString().ToLower()),
            HttpUtility.UrlEncode(Strict),
            HttpUtility.UrlEncode(PrinceOptions));

        var byteArray = Encoding.UTF8.GetBytes(postData);

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(DocRaptorUrl);
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.ContentLength = byteArray.Length;
        using (var dataStream = request.GetRequestStream()) { dataStream.Write(byteArray, 0, byteArray.Length); }

        System.IO.Stream stream = null;

        try 
        {
            using (HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse())
            {
                using (System.IO.Stream responseStream = httpResponse.GetResponseStream())
                {

                    var filepath = @"C:\Users\David\Downloads\UberwriterUSRReport.pdf";
                    HttpContext.Current.Response.ContentType = "application/pdf";

                    // let the browser know how to open the PDF document, attachment or inline, and the file name
                    HttpContext.Current.Response.AddHeader("Content-Disposition", String.Format("attachment; filename=UberwriterUSRReport.pdf"));

                    stream = new System.IO.FileStream(filepath, System.IO.FileMode.Create);

                    CopyStream(responseStream, stream);

                    long bytestToRead = stream.Length;

                    while (bytestToRead > 0)
                    {
                        if (HttpContext.Current.Response.IsClientConnected)
                        {
                            byte[] buffer = new Byte[10000];  
                            int length = stream.Read(buffer, 0, 10000);
                            HttpContext.Current.Response.OutputStream.Write(buffer, 0, length);
                            HttpContext.Current.Response.Flush();

                            bytestToRead = bytestToRead - length;
                        }
                        else
                        {
                            bytestToRead = -1;
                        }
                    }
                }
            }
        }
4

2 に答える 2

4

ブラウザに送信する前に、ファイルをハードドライブに保存するつもりですか? それがあなたが(間違って)今やっていることだからです。

書き込みアクションを using ステートメントで囲むのが最善です。ストリームをどこにも閉じていないからです。

stream = new System.IO.FileStream(filepath, System.IO.FileMode.Create);

ここで、ファイルに保存しています:

CopyStream(responseStream, stream);

次に、出力ストリーム (ファイルを保存したばかり) を読み取って、それを Response.Outputstream に書き込もうとしています。そして、すでにコピーストリームの実装があるのに、なぜここで手動で行うのでしょうか? :

HttpContext.Current.Response.OutputStream.Write(buffer, 0, length);

だから、私はそれが次のようなものであるべきだと思います:

using (HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse())
{
    using (System.IO.Stream responseStream = httpResponse.GetResponseStream())
    {
        var filepath = @"C:\Users\David\Downloads\UberwriterUSRReport.pdf";
        HttpContext.Current.Response.ContentType = "application/pdf";

        // let the browser know how to open the PDF document, attachment or inline, and the file name
        HttpContext.Current.Response.AddHeader("Content-Disposition", String.Format("attachment; filename=UberwriterUSRReport.pdf"));

        using (var stream = new System.IO.FileStream(filepath, System.IO.FileMode.Create)) {
          CopyStream(responseStream, stream);
        }

        using (var readstream = new System.IO.FileStream(filepath, System.IO.FileMode.Read)) {
            CopyStream(readstream, HttpContext.Current.Response.OutputStream);
        }
    }
}

または、ファイルをサーバーにまったく保存したくない場合は、次のようにします。

using (HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse())
{
    using (System.IO.Stream responseStream = httpResponse.GetResponseStream())
    {
        // let the browser know how to open the PDF document, attachment or inline, and the file name
        HttpContext.Current.Response.AddHeader("Content-Disposition", String.Format("attachment; filename=UberwriterUSRReport.pdf"));

      CopyStream(responseStream, HttpContext.Current.Response.OutputStream);
    }
}
于 2013-08-04T15:40:25.670 に答える