I am using Reporting Services 2005 on SQL Express with Advanced Services...
I am dipping into the SOAP API and trying to add DataSources and Reports dynamically, as is how I would like to be able to deploy them...
My problem is this:
I have a shared datasource and a report that were deployed to the server via the 'Deploy' method in VSTS...I can access that report just fine, and it obviously uses the shared datasource...
Next, I copy the .rdl file of the report I already deployed and give it another name ("NewReport.rdl"). What I want to do is add this report to the server (it's an exact copy of the functioning report with a different report name). This report should use the same shared datasource as the other report.
Here is my code:
ReportingService2005 rs = new ReportingService2005();
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
Byte [] reportDefinition = /* read in the rdl file and create byte array out of it (didn't want to paste this code, cuz you don't care...trust me, it's correct */
ReportingTest.localhost.Warning [] warnings = rs.CreateReport("NewReport", "/ReportServerTest", true, reportDefinition, null);
foreach (ReportingTest.localhost.Warning warning in warnings)
{
Console.WriteLine(warning.Message);
}
The report is added to the server just fine, but I receive this 1 warning:
Code: "rsDataSourceReferenceNotPublished"
Message: "The data set ‘AdventureWorksTestDataSource’ refers to the shared data source ‘AdventureWorksTestDataSource’, which is not published on the report server."
And then when I try to view the report, I get this exception:
"The report server cannot process the report. The data source connection information has been deleted. (rsInvalidDataSourceReference)"
I know that the datasource is there, because the other report still works just fine...and I am adding an exact COPY of that report's RDL to the server, so it SHOULD work, IMO...
Any word on this ...I haven't been able to find much on this error...they say that an 'rsInvalidDataSourceReference' is usually caused when the datasource doesn't exist on the server when the report is deployed...or the datasource is deleted after the report has been deployed, but this is not true in my case...
Thanks for any feedback!!
Russ

ReportingService2005.CreateReport() warning...
Cetin Basoz
DJ24966
Thanks for sharing.
I've got one question.
In "ReportingTest.localhost.Warning[]...", I am not sure from what class is the object ReportingTest created
Many thanks in advance for your reply.
John
anindya_mozumdar
dr.pavan
Nesim
No, they aren't...
Here is the File Structure...
Root
|
|___
|
|___DataSources
| |
| |___AdventureWorksTestDataSource
|
|___ReportServerTest
|
|___AdvenctureWorksTestReport
|
|___NewReport
Again, I'm using the same RDL structure and data that is coming from the report that IS working...i'm just re-creating that same report with a different name...that's why I'm not sure if it's a directories problem...I think ALL Datasources are assumed to be in the DataSources directory(or a subdirectory of that directory), aren't they
You may have noticed that the First Report is spelled incorrectly, but that doesn't matter...so, don't let that scream at you as a gotcha...
Thanks for your help!
Russ
Brad Younge
That suggestion helped!!!...Here is the code that allows me to do it, if anyone else runs into this problem! Thanks again!
ReportingService2005
rs = new ReportingService2005();rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
CatalogItem[] catalogItems = rs.ListChildren("/", true);
DataSourceDefinition dsDefinition = new DataSourceDefinition();
dsDefinition.CredentialRetrieval = CredentialRetrievalEnum.Store;
dsDefinition.ConnectString = @"Data Source=.\SQLExpress;Initial Catalog=AdventureWorks";
dsDefinition.Enabled = true;
dsDefinition.OriginalConnectStringExpressionBased = false;
dsDefinition.WindowsCredentials = false;
dsDefinition.ImpersonateUser = false;
dsDefinition.Extension = "SQL";
dsDefinition.Prompt = null;
dsDefinition.UserName = "username";
dsDefinition.Password = "p@ssword";
Byte[] reportDefinition = null; try
{
System.IO.FileStream stream = System.IO.File.OpenRead("DynamicTestReport.rdl");
reportDefinition = new Byte[stream.Length];
stream.Read(reportDefinition, 0, (int)stream.Length);
stream.Close();
}
catch (System.IO.IOException ioe)
{
Console.WriteLine(ioe.Message);
}
try
{
rs.CreateDataSource("DynamicDataSource", "/Data Sources", true, dsDefinition, null);
ReportingTest.localhost.Warning [] warnings = rs.CreateReport("DynamicTestReport", "/ReportServerTest", true, reportDefinition, null);
DataSource[] dataSources = rs.GetItemDataSources("/ReportServerTest/DynamicTestReport"); foreach (DataSource ds in dataSources)
{
if (ds.Item.GetType() == typeof(ReportingTest.localhost.InvalidDataSourceReference))
{
DataSource newDS = new DataSource();
DataSourceReference dsRef = new DataSourceReference();
dsRef.Reference = "/Data Sources/DynamicDataSource";
newDS.Item = dsRef;
newDS.Name = "DynamicDataSource";
DataSource[] newDataSources = new DataSource[]{newDS};
rs.SetItemDataSources("/ReportServerTest/DynamicTestReport", newDataSources);
}
}
}
catch (SoapException ex)
{
Console.WriteLine(ex.Message);
}
Wallace Welles
I am publishing it to the same folder on the same server...the reports are right next to each other...
Here is the 'DataSources' excerpt of the XML...
<DataSources>
<DataSource Name="AdventureWorksTestDataSource">
<DataSourceReference>AdventureWorksTestDataSource</DataSourceReference>
<rd:DataSourceID>ea3ad893-2132-478e-94fb-9fdff9803ed5</rd:DataSourceID>
</DataSource>
</DataSources>
I can do a GetReportDefinition on the ReportingService2005 object and get the original report, and it will return the exact RDL file that I'm using to upload...
Any other ideas
Thanks for the help...
Ale Contenti
I assume you published this report with the designer, am I correct
The designer publishes reports in two passes. First it publishes the report definition via CreateReport(), and then it calls SetItemDataSources() to bind the data sources. This second call to SetItemDataSources() sets the location and logon options for the data source. Essentially it "fixes up" the data source references to point to the location that the designer will actually put them. There is not really anything special about the "Data Sources" folder... It is just the default location where the designer will put data sources.
Unfortunately, the new location of the data source is not reflected in the RDL that comes out of GetReportDefinition() because by design this returns exactly the RDL that was published.
If you want to emulate the behavior of the designer in order to perform a copy, then you will have to first call CreateReport() to publish the report, find the data sources (use GetItemDataSources()), and then resolve the data sources by calling SetItemDataSources() on the new copy of the report.