0

我确信我的问题的标题没有多大意义,但我现在想不通。

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

为了实现这一点,我使用了以下方法:

  1. 在 MyPage.cshtml 中添加一个 jQuery 弹出窗口(我需要在此弹出窗口中报告内容)
  2. 当此弹出窗口打开时(在某些客户端操作上),我向第二页 proxyPage.aspx 发出 jquery ajax 请求
  3. 在代理页面上,我使用网络凭据向报告服务器发出 Web 请求并获取报告 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 中那样发送网络凭据,因此我会收到输入凭据的提示。

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

4

1 回答 1

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 文件夹。您可以在 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 脚本的 .bat:

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

有了这个,您可以在服务器上配置一个计划任务来每天调用 .bat 文件并清理应用程序的临时文件夹。

于 2013-04-28T01:20:23.807 回答