2011-01-04 10 views
2

xmlファイルを読み込み、NPOIライブラリを使用してExcelワークブックにデータを読み込む解析アプリケーションを構築しました。もともと、私はそれを私の.net Webアプリケーションの一部として持っていて、NPOIからMemoryStreamを取得し、ブラウザがそれをダウンロードするようにResponseオブジェクトに書き込みます。私はその後、WindowsサービスでホストされているWCF netTcpサービスに解析を移しました。通信は素晴らしい作品が、私は、WCFサービスからのMemoryStreamを返し、レスポンスにそれを書くとき、私は次のエラーを取得する:WCF MemoryStreamの戻り値の型をHTTP応答オブジェクトに書き込んでExcelファイルとしてダウンロードできますか?

Microsoft JScript runtime error: Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed.

私の質問は:それはから渡されるとき、ストリームに何が起こります私のクライアントにwcfサービス?ストリームは元々は私がレスポンスに書いていたNPOIとまったく同じストリームです(理論的には)。この仕事をするために私がクライアントで必要とする特別な処理はありますか?ここで

は私のクライアントコードである:(例外はあなたがIEを使っている場合は試してみResponse.Endの()

string filename = "test.xls"; 

ms = client.GetExportedFile(); 
byte[] b = ms.ToArray(); 

ms.Flush(); 
ms.Close(); 

Response.Clear(); 
Response.ContentType = "application/vnd.ms-excel"; 
Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", filename)); 
Response.AddHeader("Content-Length", b.Length.ToString()); 
Response.BinaryWrite(b); 
Response.End(); 
+0

?どうやらIEにはこのシナリオやそれに似た何かの問題がありました。 – KeithS

+0

私はIE 8でテストしています。FireFoxは私の会社では許可されていません:( – norepro

答えて

2

あなたは(例外の詳細を見つけるためにSys.WebForms.PageRequestManagerParserErrorExceptionを検索)アップデートパネルで部分ページ更新を要求するストリームをretrunているように見えます。

ストリームのみをフルページ要求(GET/POSTは特定の種類の応答が必要なページのスクリプトではなく、ブラウザ自体によって発行されたもの)に戻していることを確認してください。

+0

私はサービス側で私の応答メッセージを正しく作成した後、これも問題でした。その特定の問題を修正するための更新パネルへのポストバックトリガーとして。 – norepro

0

いくつかのことを投げつけます。どうやらそれは、コンテンツのデータはあまり推測します他のブラウザよりもタイプ:

  • 公共プラグマヘッダーを指定し、CacheControlヘッダーを必須-再検証

  • 明示的にコンテンツtを指定してみてください。転送エンコード:Response.AddHeader("Content-Transfer-Encoding","binary");

1

解決策が見つかったhere。将来的に誰かを助ける場合に備えて、私の長年の回答があります。まず、netTcpは真のストリーミングをサポートせず、バッファリングだけをサポートします。この記事では、basicHttpだけがストリーミングをサポートしていると述べていますが、これはwsHttpでこれを正常にテストしたためではありません。私のクライアントサイドの設定ファイルには、2つのバインディング定義があります。 1つはnetTcp、もう1つはwsHttpです(ストリーミング以外のすべての通信ではまだnetTcpを使用します)。 basicHttpを使用している場合、 'transferMode'属性を 'Streamed'に設定する必要があります.wsHttpはその属性を許可しません。

次に、私がMessageBodyMemberとして定義したメンバーを定義したサービスで新しいDataContractを定義する必要がありました。このメンバは、型のMemoryStreamは次のとおりです。

[MessageContract] 
public class FileDownloadMessage 
{ 
    [MessageBodyMember(Order = 1)] 
    public System.IO.MemoryStream FileByteStream; 
} 

そして、元々のMemoryStreamを返していましたOperationContractのために、私は新しいFileDownloadMessageのデータコントラクトを返すように変更:

[OperationContract] 
FileDownloadMessage GetExportedFile(); 

その契約の実装は次のとおりです。

public FileDownloadMessage GetExportedFile() 
{ 
    FileDownloadMessage f = new FileDownloadMessage(); 
    f.FileByteStream = new MemoryStream(); 

    if (ProgressMonitor.Status == ProcessStatus.CompletedReadyForExport) 
    { 
     f.FileByteStream = ProgressMonitor.ExportedFileData; 

     ProgressMonitor.Status = ProcessStatus.Ready; 
    } 
    else 
    { 
     f.FileByteStream = null; 
    } 

    return f; 
} 

これで、WCFサービスは他の付随するメタデータなしでストリームを返しているので、私のWebページのResponseオブジェクトは正しく解析できますEストリーム:

MemoryStream ms = new MemoryStream(); 
string filename = "test.xls"; 

// the code file from the wcf service includes a get method to get the 
// MessageBodyMember directly 
ms = streamingClient.GetExportedFile(); 
byte[] b = ms.ToArray(); 

ms.Flush(); 
ms.Close(); 

Response.Clear(); 
Response.ContentType = "application/vnd.ms-excel"; 
Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", filename)); 
Response.AddHeader("Content-Length", b.Length.ToString()); 
Response.BinaryWrite(b); 
Response.End(); 

私の設定は次のようになります。あなたはこれをテストするために使用しているブラウザ

<wsHttpBinding> 
    <binding name="WSHttpBindingEndPoint" closeTimeout="00:01:00" 
      openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
      bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" 
      maxBufferPoolSize="524288" maxReceivedMessageSize="655360" 
      messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" 
      allowCookies="false"> 
     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="1638400" 
       maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
     <reliableSession ordered="true" inactivityTimeout="00:10:00" 
       enabled="false" /> 
     <security mode="Message"> 
      <transport clientCredentialType="Windows" proxyCredentialType="None" 
        realm="" /> 
      <message clientCredentialType="Windows" negotiateServiceCredential="true" 
        algorithmSuite="Default" /> 
     </security> 
    </binding> 
</wsHttpBinding> 
<netTcpBinding> 
    <binding name="NetTcpBindingEndPoint" closeTimeout="00:01:00" 
     openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
     transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" 
     hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288" 
     maxBufferSize="655360" maxConnections="10" maxReceivedMessageSize="655360"> 
     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="1638400" 
      maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
     <reliableSession ordered="true" inactivityTimeout="00:10:00" 
      enabled="false" /> 
     <security mode="Transport"> 
      <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" /> 
      <message clientCredentialType="Windows" /> 
     </security> 
    </binding> 
</netTcpBinding> 
関連する問題