Using TeamCity to deploy SSRS 2008 R2 Reporting Projects - reporting-services

We are looking to integrate our SSRS 2008 R2 projects into our automated build process. Currently three times a week TeamCity builds and deploys our C# codebase. We'd like to add the SSRS report projects to that. The RDL files are currently in a Subversion source control repository.

You can use Report Server Web Service for this purpose. It has CreateItem method that uploads report to Reporting Service.
To created C# project that uploads rdl files you will need to create proxy class for your ReportService2010.asmx endpoint and then use is it like this:
ReportingService2010 reportingService = new ReportingService2010();
reportingService.Url = url + "/ReportService2010.asmx";
reportingService.Credentials = new System.Net.NetworkCredential(username, password, domain);
Microsoft.SqlServer.ReportingServices2010.Warning[] warnings = null;
using (FileStream reportStream = new FileStream("c:\\report.rdl",
FileMode.Open, FileAccess.Read))
{
using (MemoryStream ms = new MemoryStream())
{
reportStream.CopyTo(ms);
CatalogItem report = reportingService.CreateCatalogItem(
"Report",
"Report1",
"/",
true,
ms.ToArray(),
null,
out warnings);
}
}

Related

The given key was not present in the dictionary - Visual studio SSDT Deploy

I have a SSDT project in Visual Studio 2017 and multiple reports working off a shared data source. I can build all the reports and also preview them with the ability to refresh the data. However when I click deploy I receive the error message
Error : The given key was not present in the dictionary.
I have checked the project deployment details e.g (target sever details, Target Report Folder etc.) and they are all correct. Could anyone advise the best way to debug this error?
Visual Studio Error
Deployment Settings
I had exactly the same problem using Microsoft Reporting Services 1.17 installed from Extensions and Updates in VS2017 15.3.5. I debugged with Visual Studio and decompiled with JetBrains dotPeek which pointed to an error in Microsoft.ReportingServices.BuildProcess.dll. Connection properties were being looked up by URL in a dictionary. As far as I can see, this dictionary never gets populated.
The solution was to uninstall the extension and install SSDT for Visual Studio 2017 (15.3.0 preview).
Thanks for everyone's feedback. I found the bug and will release a fix with the next version of the Reporting Services VSIX.
Thanks,
Matt
There is an .rdl.data file in the report project directory next to your .rdl file. If you close Report Designer, delete that file, and try and preview again, hope this helps.
I came across with the same issue. The problem was that I had no issues when I deploy my report and I tried to access it through URL, but when I tried to access programmatically the browser launch this error 'The given key was not present in the dictionary'.I investigated and found that I was not set up the visibility flag as 'false' on the code.
https://msdn.microsoft.com/en-us/library/microsoft.reporting.webforms.reportparameter.aspx
ReportParameter(String, String, Boolean)
Instantiates a new ReportParameter with a name, a value, and a visibility flag.
Finally, my code was something sort of this:
this.rptViewer.Reset();
rptViewer.ProcessingMode = Microsoft.Reporting.WebForms.ProcessingMode.Remote;
MyReportServerCredentials credencial = new MyReportServerCredentials();
rptViewer.ServerReport.ReportServerCredentials = credencial;
this.rptViewer.ServerReport.ReportServerUrl = new System.Uri(this.ReportServerUrl);
this.rptViewer.ServerReport.ReportPath = ReportUrl;
this.rptViewer.ServerReport.ReportServerUrl = new System.Uri(this.ReportServerUrl);
this.rptViewer.ServerReport.ReportPath = ReportUrl;
ReportParameter p1 = new ReportParameter("param1", new string[] { null }, false);
ReportParameter p2 = new ReportParameter("param2", new string[] { null }, false);
ReportParameter p3 = new ReportParameter("param3", new string[] { null }, false);
ReportParameter p4 = new ReportParameter("param4", new string[] { null }, false);
this.rptViewer.ServerReport.SetParameters(new ReportParameter[] { p1, p2, p3, p4 });
this.rptViewer.AsyncRendering = false;
this.rptViewer.SizeToReportContent = true;
this.rptViewer.ServerReport.Refresh();
I hope it helps!

Method not found: Microsoft.AnalysisServices

I have created an ETL setup for a datawarehouse with SSIS packages.
Everything is working fine until the very last step which is a "Analysis Services Processing Task Editor"
Whenever I add my cube and press ok I get the following error:
"Method not found: "'Void Microsoft.AnalysisServices.Commands.ProcessCommand.set_Type(Microsoft.AnalysisServices.ProcessType)'.
I suspect there is some issue with a DLL, but I'm not sure which.
I found a Microsoft.AnalysisServices.dll under my SQL Server install (C:\Program Files (x86)\Microsoft SQL Server\120\SDK\Assemblies)
I did not find it in my Visual Studio installation folders.
I was able to found a workaround.
I was trying to reproduce the problem with the AdventureWorks dataset, to verify that the problem was occuring due to the .dll and not my cube or anything else.
So I created a new OLTP & DWH with Cube from the AdventureWorks dataset and created a new SSIS project where the only step was to process the cube.
With this setup I did not get the same error as I did on the original project, seemingly, there was nothing wrong with the .dll?
However I also tried changing the target server and cube to my original one, and to my surprise it worked!
So i saved that package and imported it into my original project and excecuted the package from there and it works.
EDIT: Please also see Pavel's possbile solution.
Strange thing, if we create new SSIS project in Project deployment mode, leave 2017 version, and deploy it on our 2016 SSIS services - all is working perfectly fine. So... we just need to migrate to the Project deployment mode ))) – Pavel Botygin
We have same problem.
One interesting thing: you can try to switch your project compatibility to SQL Server vNext, then create your processing task normally, clicking OK and other stuff successfully (what a miracle it is!), then switch back to desired version and deploy.
But if you have Script Tasks in the same package - then you can try other workaround (which I'm actually using now). Use a Script Task to populate a variable (User::DimensionsProcessingCommand in my example) for the "Analysis Services Execute DDL Task". It's little complicated way, but very useful in the future.
public void Main()
{
Boolean tstFire = false;
Microsoft.AnalysisServices.Server myServer = new Microsoft.AnalysisServices.Server();
//Get connection to SSAS database from package
ConnectionManager myConn = Dts.Connections["SSAS"];
//Template for future use
String ProcessingCommandTemplate = "<Batch xmlns=\"http://schemas.microsoft.com/analysisservices/2003/engine\"><Parallel>XXXXXXX</Parallel></Batch>";
String myProcessingCommand = "";
//Array for gathering dimensions w/o duplicates
Dictionary<Dimension, Cube> amoDimDictionary = new Dictionary<Dimension, Cube>();
String myServerName = myConn.ConnectionString;
String myDatabaseName = myConn.Properties["InitialCatalog"].GetValue(myConn).ToString();
//Connect to SSAS server instance
myServer.Connect(myServerName);
Database amoDb = myServer.Databases.FindByName(myDatabaseName);
//Get all dimensions used in cubes
foreach (Cube amoCube in amoDb.Cubes)
{
foreach (CubeDimension amoDimension in amoCube.Dimensions)
{
if (!amoDimDictionary.ContainsKey(amoDimension.Dimension))
{
amoDimDictionary.Add(amoDimension.Dimension, amoCube);
}
}
}
//Start XML capture Dimensions
myServer.CaptureXml = true;
foreach (Dimension amoDimension in amoDimDictionary.Keys)
{
if (amoDimension.State == AnalysisState.Unprocessed)
{
amoDimension.Process(ProcessType.ProcessFull);
}
else
{
amoDimension.Process(ProcessType.ProcessUpdate);
}
}
myServer.CaptureXml = false;
//Build command
foreach (String strXML in myServer.CaptureLog)
{
myProcessingCommand = myProcessingCommand + strXML.ToString();
}
myProcessingCommand = ProcessingCommandTemplate.Replace("XXXXXXX", myProcessingCommand);
Dts.Variables["User::DimensionsProcessingCommand"].Value = myProcessingCommand.ToString();
//Command output to see at runtime from VS 2015
Dts.Events.FireInformation(1, "", Dts.Variables["User::DimensionsProcessingCommand"].Value.ToString(), "", 0, ref tstFire);
P.S.
On our DEV machine are installed from scratch: SQL Server 2016, Visual Studio 2015, SSDT 17.1
When we were trying to develop some SSIS packages under SQL Server 2016 compatibility - we stumbled on so many problems... so we just stopped counting them. GAC is googled and tuned back and forth without any result.
14.0 Microsoft DEV Environment seems so buggy and... just broken if you try to create something under 13.0 and lower versions.
This MS Forum post has the following advice.
If it exists, cut and paste the following folder from the GAC to somewhere else.
C:\Windows\Microsoft.NET\assembly\GAC_MSIL\Microsoft.AnalysisServices.DeploymentEngine
Then, rebuild the project.
Right click on the project
Click properties
Expand Configuration Properties -> select Deployment
At The Target Server : Enter \ < SSAS Instace Name> ( Make Sure the SSAS Server Is Multidimensional SSAS Instance )
Click Apply
Save Project. Restart the IDE ( SSDT )
Start The SSDT -> Select The Project - > And Rebuilt Solution \ Rebuilt Project.
Test again.
This seems to be because of a deployment version that is not supported by VS-2015 components.
Go to Project-> Properties
In Configuration Properties -> General
Set TargetServerVersion To SQL Server 2017

SFTP Add-on/Extension for SSIS to pull file from SFTP in Visual Studio 2015

Trying to create an ETL process in SSIS using Visual Studio 2015 express to pull .csv files from an SFTP. Came across an add-on for older Visual studio versions but wasnt able to locate an 'SFTP Task' for VS 2015. IS there one that exists?
Here is what I found for older versions of VS:
https://ssisextensions.codeplex.com/
I am doing something similar on Script Tasks, it is not particularly hard to code a custom task for reuse but overkill for me
Using SSH.Net from nuget (https://www.nuget.org/packages/SSH.NET)
My working code is for upload instead of download, but it should get you started:
using Renci.SshNet;
using System.IO;
...
string src = ...;
string dst = ...;
string host = ...;
int port = ...;
string user = ...;
string pwd = ...;
using (var client = new SftpClient(host, port, user, pwd))
{
client.Connect();
client.ChangeDirectory(#"Test");
FileStream srcFile = new FileStream(src, FileMode.Open);
client.UploadFile(srcFile, dst);
}

SSRS - Obtaining the physical report files

Basically I have a reports server which contains loads of "My Reports" reports which I need to migrate to a new SSRS server.
Question:
Is their an easy way to obtain all the physical.RDL files without having to export the files one-by-one from the old server interface and then upload using the new servers interface?
Looking forward to your reply
Steven
There is a third party tool available here that will allow you to batch download / upload rdls.
http://sqldbatips.com/showarticle.asp?ID=62
You could write a small .NET app to retrieve them all, using the SSRS Web Service API. The article on the GetItemDefinition method has sample code to get a single file, here's a relevant snippet (copy/paste alert!):
ReportingService2010 rs = new ReportingService2010();
rs.Url = "http://<Server Name>/_vti_bin/ReportServer/ReportService2010.asmx";
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
string reportName = "http://<Server Name>/Docs/Documents"
+ "/AdventureWorks Sample Reports/Sales Order Detail.rdl";
byte[] reportDefinition = null;
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
try
{
reportDefinition = rs.GetItemDefinition(reportName);
MemoryStream stream = new MemoryStream(reportDefinition);
string myDocumentsFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
doc.Load(stream);
doc.Save(Path.Combine(myDocumentsFolder, "Sales Order Detail.rdl"));
}
If you write a little loop around (part of) this code you may be able to quickly grab all the files.

SSRS engine

This is regarding SSRS engine. For my project we are not going to buy SQL server software. Instead of what I just want to know, is there any posibility to use only SSRS engine. So that I can have the ref. (DLL) And then I can use wherever I want.
Please help on this.
If we don't consider the technical aspects of getting SSRS to run without SQL Server, you still need SQL Server for the license. SSRS is an integrated part of SQL Server, not a standalone component.
So no, without buying SQL Server licenses, you cannot use SSRS, even if you were technically able to do it, which I doubt anyway.
SQL Server Express, the free one, comes with Reporting Services. No need to shell out for a full blown SQL Server.
http://www.microsoft.com/Sqlserver/2005/en/us/express.aspx
The SQL Server Reporting services engine is not just a dll. So it will be not just as simple as adding a ref.
You typically have to deploy reports to a webserver and invoke the reports though there.
I'd advise you to look here: http://en.wikipedia.org/wiki/SQL_Server_Reporting_Services
You can create local reports that are not stored in a database if that's what you mean.
http://msdn.microsoft.com/en-us/library/ms252067(v=vs.80).aspx
SSRS needs SQL Server as the ReportServer and ReportServerTempDB databases must be hosted on SQL Server. SQL Agent is also used by the SSRS Service:
https://msdn.microsoft.com/en-us/library/ms156421.aspx
You could try PowerBI as an alternative solution for your project if you are not going to purchase SQL Server software licenses:
https://powerbi.microsoft.com/en-us/
You need to create local reports (.RDLC) using BIDS in visual studio. To render these reports, you need to write code to pass parameters and datasets values. You need to add reference of Report Viewer and use LocalReport to call Render method. It will return you byte array of rendered report.
using (Microsoft.Reporting.WebForms.LocalReport report = new LocalReport())
{
string appPath = AppDomain.CurrentDomain.BaseDirectory;
report.ReportPath = System.IO.Path.Combine(appPath, "Reports", RDLName.ToString());
foreach (KeyValuePair<string, object> dataSource in ReportDataSource)
{
report.DataSources.Add(new ReportDataSource(dataSource.Key, dataSource.Value));
}
if (ReportParameters != null)
{
foreach (KeyValuePair<string, object> parameter in ReportParameters)
{
report.SetParameters(new ReportParameter(parameter.Key, (parameter.Value == null ? null : parameter.Value.ToString())));
}
}
result = report.Render(Format);
report.Dispose();
return result;
}
using the report viewer runtime
download from microsoft
tutorial to use it
you can render rdl files and rdlc files locally, you just have to execute the query yourself