C# WCF MemoryStream返回类型是否可以写入Http响应对象以作为Excel文件下载?
我构建了一个解析应用程序,它读取xml文件,并使用库填充Excel工作簿。最初,我将其作为.net web应用程序的一部分,并从NPOI获取MemoryStream,然后将其写入响应对象,以便浏览器下载它。此后,我将解析移到了托管在Windows服务中的WCF netTcp服务。通信效果很好,但当我从WCF服务返回MemoryStream并将其写入响应时,我得到以下错误: Microsoft JScript运行时错误: Sys.WebForms.PageRequestManagerParserErrorException: 从服务器接收的消息 无法分析 我的问题是:当流从wcf服务传递到我的客户机时,它会发生什么?该流(理论上)与我最初写入响应的NPOI流完全相同。是否有任何特殊的处理,我需要做的客户,使这项工作 这是我的客户机代码:(在Response.End()处引发异常)C# WCF MemoryStream返回类型是否可以写入Http响应对象以作为Excel文件下载?,c#,wcf,httpresponse,memorystream,npoi,C#,Wcf,Httpresponse,Memorystream,Npoi,我构建了一个解析应用程序,它读取xml文件,并使用库填充Excel工作簿。最初,我将其作为.net web应用程序的一部分,并从NPOI获取MemoryStream,然后将其写入响应对象,以便浏览器下载它。此后,我将解析移到了托管在Windows服务中的WCF netTcp服务。通信效果很好,但当我从WCF服务返回MemoryStream并将其写入响应时,我得到以下错误: Microsoft JScript运行时错误: Sys.WebForms.PageRequestManagerParserE
如果您使用IE,可以尝试以下几点;显然,与其他浏览器相比,IE从内容类型推断的数据更少:
- 指定公共Pragma标头和必须重新验证CacheControl标头
- 尝试显式指定内容传输编码:
Response.AddHeader(“内容传输编码”、“二进制”);
[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服务返回的流没有任何其他附带元数据,因此我的网页的响应对象可以正确解析流:
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>
您使用哪个浏览器来测试此问题?显然IE在这种情况下遇到了一些问题或类似问题。我正在使用IE 8进行测试。我的公司不允许使用FireFox:(在服务端正确构建响应消息后,我发现这也是一个问题,在后台仍然存在。我只是简单地将下载按钮作为回发触发器添加到更新面板中,以修复该特定问题。谢谢!
<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>