现在让我们来看看...我有一个AngularJS SPA。我想在我的视图页面上提供链接,单击该链接后,打开一个新选项卡并以PDF格式启动预先存在的SSRS报告。从技术上讲,我要做的是:在我的存储库中呈现SSRS报告,通过我的WEB API传递给我的SPA,然后在新标签中显示。
在进一步说明之前的一个重要注意事项:此设置,方法,方法在Visual Studio中的本地计算机上完美运行。当我将SPA移动到远程Web服务器(托管SSRS的同一台服务器)时,我遇到了问题。
我的风景:
本地开发机器(Windows 7 Pro,VS2015 Pro)
Server1(Win Server 2012R2):主机IIS(8),SPA,SQL(2014)和SSRS
Server2(Win Server 2012R2)。主机SSRS(SQL 2012)数据源(恰好是SSAS多维数据集,但我认为不重要)。
在我的本地开发机器上:
如上所述,解决方案可以通过Visual Studio正常工作。我本地机器上解决方案的唯一部分是SPA。 SSRS和SQL部分位于远程位置。我可以启动我的SPA,点击链接,打开包含PDF报告的新标签页。我也可以直接拨打网络API并显示PDF报告(http://localhost:3040/api/dataservice/ProductivityReportH/)
问题1
浏览Server1上已部署的SPA版本,应用程序显示正常。但是,如果我点击报告超链接,我会收到以下消息:
您想从Server1打开或保存ProductivityReportH /(3.28KB)吗?
无论我点击什么(打开,保存,取消)都没有任何反应。
如果我尝试直接通过API启动报告,我会收到相同的消息。控制台窗口中没有显示错误。我在Server1日志文件中找不到任何错误。
在Server1上:我可以通过SSRS报告查看器显示报告。
问题1A
使用Server1上的浏览器,我可以正常显示应用程序。但是,如果我点击报告超链接,我会收到与问题1相同的消息。如果我尝试直接通过Web API启动报告(http://Server1/projecttracker/api/dataservice/ProductivityReportH/) 在Server1上,我收到相同的消息。
非常感谢任何想法
我的SPA设置:
查看页面:
<div class="view indent">
<div class="container">
<h2>Productivity Reports Method 1</h2>
<a ng-href='#here' ng-click="hproductivityreport()">Launch</a><br>
</div>
我的控制器:
(function () {
var ProjectsController = function ($scope, $window) {
$scope.hproductivityreport = function () {
$window.open('api/dataservice/ProductivityReportH/', '_blank');
};
}
ProjectsController.$inject = ['$scope', '$window'];
angular.module('ReportTracker').controller('ProjectsController', ProjectsController)
}());
WEB API:
using ProjectTracker.Repository;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web;
using System.Web.Http;
namespace ProjectTracker.Model
{
[Authorize]
public class DataServiceController : ApiController
{
IProjectTracker _ProjectTrackerRepository;
public DataServiceController()
: this(null)
{
}
public DataServiceController(IProjectTracker Repo)
{
_ProjectTrackerRepository = Repo ?? new ProjectTrackerRepository ();
}
[HttpGet]
public HttpResponseMessage ProductivityReportH()
{
var result = new HttpResponseMessage(HttpStatusCode.OK);
byte[] bytes = _ProjectTrackerRepository.RenderProductivityReport("Hibble, Norman");
Stream stream = new MemoryStream(bytes);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
return result;
}
}
}
存储库:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
namespace ProjectTracker.Repository
{
public class ProjectTrackerRepository : RepositoryBase<ProjectTrackerContext>, IProjectTracker
{
ProjectTrackerContext _Context;
public ProjectTrackerRepository()
{
_Context = new ProjectTrackerContext();
}
public Byte[] RenderProductivityReport(string _sManager)
{
Server1.ReportExecutionService rs = new Server1.ReportExecutionService();
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
rs.Url = "http://Server1/reportserver/ReportExecution2005.asmx";
// Render arguments
byte[] result = null;
string reportPath = "/Staff Client Services/StaffProductivity";
string format = "PDF";
string historyID = null;
string devInfo = @"<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";
//Create the list of parameters that will be passed to the report
List<Server1.ParameterValue> lstParameterValues = new List<Server1.ParameterValue>();
Server1.ParameterValue aParameter = new Server1.ParameterValue();
aParameter.Name = "SupervisorSupervisorName";
aParameter.Value = "[Supervisor].[Supervisor Name].&[" + _sManager + "]";
lstParameterValues.Add(aParameter);
Server1.ParameterValue bParameter = new Server1.ParameterValue();
bParameter.Name = "PayPeriodPayPeriodYear";
bParameter.Value = "[Pay Period].[Pay Period Year].&[2015]";
lstParameterValues.Add(bParameter);
int index = 0;
Server1.ParameterValue[] parameterValues = new Server1.ParameterValue[lstParameterValues.Count];
foreach (Server1.ParameterValue parameterValue in lstParameterValues)
{
parameterValues[index] = parameterValue;
index++;
}
string encoding;
string mimeType;
string extension;
Server1.Warning[] warnings = null;
string[] streamIDs = null;
Server1.ExecutionInfo execInfo = new Server1.ExecutionInfo();
Server1.ExecutionHeader execHeader = new Server1.ExecutionHeader();
rs.ExecutionHeaderValue = execHeader;
execInfo = rs.LoadReport(reportPath, historyID);
rs.SetExecutionParameters(parameterValues, "en-us");
String SessionId = rs.ExecutionHeaderValue.ExecutionID;
try
{
result = rs.Render(format, devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);
execInfo = rs.GetExecutionInfo();
}
catch (Exception e)
{
Exception Errr = e.InnerException;
}
return result;
}
}
}
答案 0 :(得分:0)
最后!对于那些感兴趣的人......
近两年前发现了这一点。
AppPool Permission Issue with Accessing Report Server
特别是以下评论:
除了在Windows Server 2008 R2上运行的IIS和报表服务器之外,其他情况几乎相同。我曾经使用自己的应用程序池运行asp.net应用程序,一切正常。当我将应用程序更改为DefaultAppPool时(由于不同的问题),我收到了权限问题。我将DefaultAppPool的标识从ApplicationPoolIdentity更改为LocalSystem(在IIS中,高级设置),然后再次运行。
将Web服务器默认应用程序池更改为LocalSystem,并且通过我的AngularJS SPA从SSAS多维数据集呈现PDF报告。