Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WCF MemoryStream返回类型是否可以写入Http响应对象以作为Excel文件下载?_C#_Wcf_Httpresponse_Memorystream_Npoi - Fatal编程技术网

C# WCF MemoryStream返回类型是否可以写入Http响应对象以作为Excel文件下载?

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

我构建了一个解析应用程序,它读取xml文件,并使用库填充Excel工作簿。最初,我将其作为.net web应用程序的一部分,并从NPOI获取MemoryStream,然后将其写入响应对象,以便浏览器下载它。此后,我将解析移到了托管在Windows服务中的WCF netTcp服务。通信效果很好,但当我从WCF服务返回MemoryStream并将其写入响应时,我得到以下错误:

Microsoft JScript运行时错误: Sys.WebForms.PageRequestManagerParserErrorException: 从服务器接收的消息 无法分析

我的问题是:当流从wcf服务传递到我的客户机时,它会发生什么?该流(理论上)与我最初写入响应的NPOI流完全相同。是否有任何特殊的处理,我需要做的客户,使这项工作

这是我的客户机代码:(在Response.End()处引发异常)


如果您使用IE,可以尝试以下几点;显然,与其他浏览器相比,IE从内容类型推断的数据更少:

  • 指定公共Pragma标头和必须重新验证CacheControl标头

  • 尝试显式指定内容传输编码:
    Response.AddHeader(“内容传输编码”、“二进制”);


您似乎通过更新面板重新运行stream以请求部分页面更新(搜索Sys.WebForms.PageRequestManagerParserErrorException以查找有关异常的更多详细信息)

确保您仅将流重新运行到完整页面请求(GET/POST由浏览器本身发出,而不是由页面上需要某种特定类型响应的脚本发出).

我找到了解决方案。这是我的冗长回答,以防将来对某人有所帮助。首先,netTcp不支持真正的流式传输,只支持缓冲。文章指出,只有basicHttp支持流式传输,但事实并非如此,因为我已经用wsHttp成功地测试了这一点。在我的客户端配置文件中,我现在有2个绑定定义;1用于netTcp,另一个用于wsHttp(对于我所有的非流式通信,我仍然希望使用netTcp)。如果使用basicHttp,则需要将“transferMode”属性设置为“Streamed”-wsHttp不允许该属性

然后,我必须在我的服务中定义一个新的DataContract,它定义了一个成员,我将该成员定义为MessageBodyMember。该成员的类型为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服务返回的流没有任何其他附带元数据,因此我的网页的响应对象可以正确解析流:

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>