0

我确信我的问题标题没有太大意义,但现在我想不起来了。将身份验证标头传递给iframe中的图片请求

问题:我的主要任务是在ASP.NET MVC应用程序的一个页面内的弹出窗口中显示SSRS报告的所有页面

要做到这一点我用下面的方法:

  1. 添加在MyPage.cshtml一个jQuery弹出(我需要这个报告里面弹出内容)
  2. 在这个弹出打开(在某些客户端动作),我做一个jquery ajax请求到第二页proxyPage.aspx
  3. 在代理页面我做的WebRequest与网络凭证的reportserver并得到报告HTML

    WebRequest request = WebRequest.Create("http://MyReportServer/ReportServer?/ MyReportName&rs:Command=Render&rs:Format =HTML4.0&rc:Toolbar=false&Param1=blabla123"); 
        request.Credentials = new NetworkCredential(MYUSERNAME, MYPASSWORD); 
        HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
        Stream receiveStream = response.GetResponseStream(); 
        StreamReader readStream = new StreamReader(receiveStream, System.Text.Encoding.UTF8); 
        string str = readStream.ReadToEnd(); 
        Response.Write(str); 
    
  4. 来自proxyPage的HTML我在弹出窗口中使用div编写代码或使用iframe在其中显示完整代理页面。

  5. 到这里一切顺利的话,然后我得到了另一个问题为此我写了这个问题

  6. 当报告的HTML,在弹出的获取呈现它使请求报告服务器去取回嵌入在报告中的图像。

因为这些请求报告服务器不像我在步骤3中那样发送网络凭证,所以我得到提示输入凭证。

我需要一种方法,通过这种方法,这些图像请求可能以某种方式通过我之前提供的凭据进行验证。

回答

0

SSRS将在您指定的位置流式传输资源。

private byte[] InternalRenderReport(Report report, List<ReportParameter> parameters, string format, int pageNumber, ref int totalPages, string virtualTempFolder, string physicalTempFolder) 
     { 
      CheckConnection(); 
      byte[] result = null; 
      ReportExecution2005.ReportExecutionService _execService=new ReportExecution2005.ReportExecutionService(); 


      sys = _systemService.GetCurrentSystem(); 
      _execService.Url = sys.ReportingServices.ServiceRootURL+"/ReportExecution2005.asmx"; 
      NetworkCredential credentials = new NetworkCredential(sys.ReportingServices.Credentials.UserName, 
                   sys.ReportingServices.Credentials.Password, 
                   sys.ReportingServices.Credentials.Domain); 
      _execService.Credentials=credentials; 

      ReportExecution2005.ParameterValue[] rsParams = null; 
      if (parameters != null) 
      { 
       rsParams = new ReportExecution2005.ParameterValue[parameters.Count]; 
       int x = 0; 
       foreach (ReportParameter p in parameters) 
       { 
        rsParams[x] = new ReportExecution2005.ParameterValue(); 
        rsParams[x].Name = p.ParameterName; 
        rsParams[x].Value = p.SelectedValue; 
        x++; 
       } 
      } 
      StringBuilder devInfo = new StringBuilder(); 
      if (format.ToUpper().StartsWith("HTML")) 
      { 
       devInfo.Append("<DeviceInfo>"); 
       devInfo.Append("<HTMLFragment>True</HTMLFragment>"); 
       devInfo.Append("<Section>" + pageNumber.ToString() +"</Section>"); 
       devInfo.Append("<StreamRoot>" + virtualTempFolder + "</StreamRoot>"); 
       /*devInfo.Append("<Zoom>200</Zoom>");*/ 
       devInfo.Append("</DeviceInfo>");     
      } 
      else 
       devInfo.Append("<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>"); 

      string extension; 
      string mimeType; 
      string encoding; 
      string[] streamIDs = null; 
      ReportExecution2005.Warning[] warnings = null; 




      ReportExecution2005.ExecutionHeader execHeader = new ReportExecution2005.ExecutionHeader(); 
      ReportExecution2005.ExecutionInfo rpt = _execService.LoadReport(report.ReportPath, null); 

      if(rsParams!=null) 
       _execService.SetExecutionParameters(rsParams, "en-us"); 
      _execService.ExecutionHeaderValue = execHeader; 
      _execService.ExecutionHeaderValue.ExecutionID = rpt.ExecutionID; 


      //result = _execService.Render2(format, devInfo, ReportExecution2005.PageCountMode.Actual, out extension, out mimeType, out encoding, out warnings, streamIDs); 
      result = _execService.Render(format, devInfo.ToString(), out extension, out mimeType, out encoding, out warnings, out streamIDs); 

      if (format.ToUpper().StartsWith("HTML")) 
      { 


       // For each image stream returned by the call to render, 
       // render the stream and save it to the application root 
       string FilePath = physicalTempFolder; 
       byte[] image; 
       // For each image stream returned by the call to render, 
       // render the stream and save it to the application root 
       foreach (string streamID in streamIDs) 
       { 
        image = _execService.RenderStream("HTML4.0", streamID, null, out encoding, out mimeType); 

        FileStream stream = File.OpenWrite(FilePath + streamID); 
        stream.Write(image, 0, image.Length);      
        stream.Close(); 
       } 
      } 

      rpt = _execService.GetExecutionInfo(); 
      totalPages = rpt.NumPages; 

      return result; 
     } 

这将返回原始HTML或内容推送文件。我向要部署到服务器的解决方案添加了Temp文件夹。你可以放置在临时文件夹中的web.config文件包含以下内容,以便扩展更少内容SSRS将使用流时呈现:

<?xml version="1.0" encoding="UTF-8"?> 
<configuration> 
    <system.webServer> 
    <staticContent> 

     <mimeMap fileExtension=".*" mimeType="image/png" /> 


    </staticContent> 
    <handlers> 
     <clear /> 

     <add name="StaticFile" path="*" verb="*" type="" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" scriptProcessor="" resourceType="Either" requireAccess="Read" allowPathInfo="false" preCondition="" responseBufferLimit="4194304" /> 
    </handlers> 
    </system.webServer> 
</configuration> 

然后使用下面的方法函数来获得物理和虚拟临时文件夹:

PhyscicalTempFolder= AppDomain.CurrentDomain.BaseDirectory + @"Temp\"; 
VirtualTempFolder=return Url.Content("~/Temp/"); 

最后清理每一天后,您可以添加类似一个PowerShell命令:

Remove-Item D:\xxx\WebApplications\ExternalReports\Temp\* -exclude *.config 

然后添加调用PS SC名为.bat RIPT:

powershell -command "& 'C:\xxx\Scripts\SSRSCleanTempFiles\SSRSCleanTempFiles.ps1'" 

有了这个,你可以在服务器上配置计划任务的日常.bat文件调用,并清洁你的应用程序的temp文件夹。

相关问题