Showing posts with label api. Show all posts
Showing posts with label api. Show all posts

Wednesday, March 7, 2012

ReportingService2005.CreateReport() warning...

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

Are you publishing it ot the same location? Check to see if the original report is using an absolute or relative path to the data source. If it is a relative path, then you will need to adjust it in your copy if you are publishing it to a different location.|||

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...

|||Has anyone else received this type of error?|||Where is the datasource in relation to the reports? Is it in the same folder?|||


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

|||

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.

|||

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);
}

|||

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

ReportingService2005.CreateReport() warning...

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

Are you publishing it ot the same location? Check to see if the original report is using an absolute or relative path to the data source. If it is a relative path, then you will need to adjust it in your copy if you are publishing it to a different location.|||

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...

|||Has anyone else received this type of error?|||Where is the datasource in relation to the reports? Is it in the same folder?|||


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

|||

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.

|||

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);
}

|||

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

ReportingService.Render

Hi All,
In the examples of the ReportingService API i found the render method that
renders a report to a file.
But what ever i try i cant get it to work becuase the reportPath parameter
is always incorrect.
When browsing for the report using my IE browser this is the URL:
http://localhost/ReportServer?%2ftester1%2fReport1&rs:Command=Render
I come there after typing in:
http://localhost/ReportServer
Then clicking on tester1
Then clicking on report1
Now what ever i try to put in the reportPath it does not work. Can someone
give me any pointers?
Dim rs As New ReportingService.ReportingService
rs.Credentials = System.Net.CredentialCache.DefaultCredentials
' Render arguments
Dim result As Byte() = Nothing
Dim reportPath As String = "/ReportServer/tester1/report1"
Dim format As String = "MHTML"
Dim historyID As String = Nothing
Dim devInfo As String = "<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>"
' Prepare report parameter.
Dim parameters() As ParameterValue = Nothing
Dim credentials As DataSourceCredentials() = Nothing
Dim showHideToggle As String = Nothing
Dim encoding As String
Dim mimeType As String
Dim warnings As Warning() = Nothing
Dim reportHistoryParameters As ParameterValue() = Nothing
Dim streamIDs As String() = Nothing
Dim sh As New SessionHeader
rs.SessionHeaderValue = sh
Try
result = rs.Render(reportPath, format, historyID, devInfo,
parameters, credentials, showHideToggle, encoding, mimeType,
reportHistoryParameters, warnings, streamIDs)
sh.SessionId = rs.SessionHeaderValue.SessionId
Catch e As SoapException
End Try
Try
Dim stream As FileStream = File.Create("report.pdf",
result.Length)
stream.Write(result, 0, result.Length)
stream.Close()
Catch e As Exception
End Try/tester1/report1 as path solved that problem.
But now i have other problems with the user compname\ASP.NET not having
sufficient rights.
Where can i find documentation on how to setup the security so that i can
use the render method?

ReportingService.GetServerDateTime Missing??

It seems like the ReportingService.GetServerDateTime method is missing on
the webservice API, although it should be there according to the
documentation.
Any help appreciated!
Thanks,
MartenThis is documentation bug. There is no such method.
--
This posting is provided "AS IS" with no warranties, and confers no rights.
"Marten Engblom" <me@.nospam.com> wrote in message
news:OKVjxOilEHA.948@.TK2MSFTNGP12.phx.gbl...
> It seems like the ReportingService.GetServerDateTime method is missing on
> the webservice API, although it should be there according to the
> documentation.
> Any help appreciated!
> Thanks,
> Marten
>|||Is there any other way of getting the time of the server, other than
deploying another custom webservice for it?
Thanks,
Marten
"Lev Semenets [MSFT]" <levs@.microsoft.com> wrote in message
news:%23wiyCLjlEHA.2884@.TK2MSFTNGP09.phx.gbl...
> This is documentation bug. There is no such method.
> --
> This posting is provided "AS IS" with no warranties, and confers no
> rights.
>
> "Marten Engblom" <me@.nospam.com> wrote in message
> news:OKVjxOilEHA.948@.TK2MSFTNGP12.phx.gbl...
>> It seems like the ReportingService.GetServerDateTime method is missing on
>> the webservice API, although it should be there according to the
>> documentation.
>> Any help appreciated!
>> Thanks,
>> Marten
>|||You can publish report like this and render it to CSV
<?xml version="1.0" encoding="utf-8"?>
<Report
xmlns="http://schemas.microsoft.com/sqlserver/reporting/2003/10/reportdefinition"
xmlns:rd="">http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
<RightMargin>1in</RightMargin>
<Body>
<ReportItems>
<Textbox Name="textbox1">
<CanGrow>true</CanGrow>
<Value>=DateTime.Now().ToString("yyyy-MM-dd hh:mm:ss")</Value>
</Textbox>
</ReportItems>
<Style />
<Height>0.25in</Height>
</Body>
<TopMargin>1in</TopMargin>
<Width>3.875in</Width>
<LeftMargin>1in</LeftMargin>
<BottomMargin>1in</BottomMargin>
<Language>en-US</Language>
</Report>
This posting is provided "AS IS" with no warranties, and confers no rights.
"Marten Engblom" <me@.nospam.com> wrote in message
news:eq5FntolEHA.1672@.TK2MSFTNGP14.phx.gbl...
> Is there any other way of getting the time of the server, other than
> deploying another custom webservice for it?
> Thanks,
> Marten
> "Lev Semenets [MSFT]" <levs@.microsoft.com> wrote in message
> news:%23wiyCLjlEHA.2884@.TK2MSFTNGP09.phx.gbl...
>> This is documentation bug. There is no such method.
>> --
>> This posting is provided "AS IS" with no warranties, and confers no
>> rights.
>>
>> "Marten Engblom" <me@.nospam.com> wrote in message
>> news:OKVjxOilEHA.948@.TK2MSFTNGP12.phx.gbl...
>> It seems like the ReportingService.GetServerDateTime method is missing
>> on the webservice API, although it should be there according to the
>> documentation.
>> Any help appreciated!
>> Thanks,
>> Marten
>>
>