从宁静的WCF调用中提供可下载的文件

时间:2011-10-18 16:19:00

标签: wcf jquery

我需要从一个安静的wcf服务启动文件下载,并遇到一些问题。

如果我将我的restful调用设置为GET(GET调用与删除参数并更改名称的情况相同),我可以指向浏览器,并获得一个正确响应的方法浏览器提示我下载文件,但是当收到文件时它是空的,我的标题显示内容长度为0.当一个笔记单步执行服务调用时,流是正确的。

如果我设置为POST并使用JQuery将其称为ajax调用(这是我希望的最终结果,因为我需要将一些数据传递给服务,如果需要,我可以传递URL中的数据点并使用GET)。

我的问题:

  1. 我错过了通过webHttpBinding(下面的代码)返回流的内容,这会导致我的内容实际上不会被退回吗?

  2. 是否可以以浏览器识别可下载内容类型的方式重定向jquery中收到的ajax响应,或者这是否必须使用GET?

  3. 服务代码:

       [WebInvoke(Method = "POST", UriTemplate = "UtilizationReport", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json)]
            public Stream DownloadUtilizationReport(string startDate, string endDate)
            {
                    DateTime start = DateTime.Parse(startDate);
                    DateTime end = DateTime.Parse(endDate);
                    .
                    .    
                    .
    
                    Stream stream = reportGenerator.GenerateUtilizationReport(exams);
    
                    WebOperationContext.Current.OutgoingResponse.ContentType = "text/csv";
                    WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-Disposition", "attachment; filename=MediaImport_Utilization_" + startDate + "-" + endDate + ".csv");
                    return stream;
    
    
            }
    

    端点配置:

    <system.serviceModel>
        <bindings>
          <webHttpBinding>
            <binding name="reportDownload" transferMode="StreamedResponse" />
          </webHttpBinding>
        </bindings>
        <behaviors>
          <endpointBehaviors>
            <behavior name="webHttpBehavior">
              <webHttp faultExceptionEnabled="true" />
            </behavior>
          </endpointBehaviors>
          <serviceBehaviors>
            <behavior name="">
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <services>         
          <service name="Poiesis.MediaImport.ReportingService">
            <endpoint address="rest" binding="webHttpBinding" bindingConfiguration="reportDownload" behaviorConfiguration="webHttpBehavior"
              name="restEndpoint" contract="Poiesis.MediaImport.IReportingService" />
          </service>
        </services>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
          multipleSiteBindingsEnabled="true" />
      </system.serviceModel>
    

    从POST收到的回复:

    HTTP/1.1 200 OK
    Cache-Control: private
    Content-Type: text/csv
    Server: Microsoft-IIS/7.5
    Content-Disposition: attachment; filename=MediaImport_Performance2000-01-01-2012-01-01.csv
    X-AspNet-Version: 4.0.30319
    X-Powered-By: ASP.NET
    Date: Tue, 18 Oct 2011 15:32:47 GMT
    Content-Length: 0
    

2 个答案:

答案 0 :(得分:3)

当您逐步完成服务呼叫时,请确认流中的位置设置为0;如果您的GenerateUtilizationReport方法正在写入流,但没有重置流的位置以启动,当WCF开始从中读取时,它将找不到任何其他内容。如果这是MemoryStream,只需在返回之前将其Position属性设置为0。

答案 1 :(得分:0)

将其作为GET请求并将window.location设置为服务URL。这将“欺骗”浏览器,它将开始下载。