I have recently been developing a SharePoint solution that runs Reporting Services in SharePoint integration mode. I have a Site Definition for provisioning site collections and found that when I created a page with a ListView WebPart and connected it to a Reporting Services Report Viewer WebPart I received the following message in the report viewer web part.
The item 'http://www.mysite.com/[managedurl]/[SiteCollectionUrl]/[managedurl]/[SiteCollectionUrl]/[ReportLibrary]/MyReport.rdl' cannot be found. (rsItemNotFound)
I quickly found that this is because the list view web part provides a a datarowview with a column called DocUrl that contains the server relative url to the document. But on consumption, the report viewer wewbpart prefixes this url with the site collection's url.
Example
I have a report library called "My Reports" that contains a report called "Report1.rdl". When on the root of the web application the site collection url is "http://www.mysite.com/" and the server relative url of the document is "/My Reports/Report1.rdl". The report view web part adds them together to get.
http://www.mysite.com/My Reports/Report1.rdl - That's fine
Now lets consider the effect of the site collection being on a managed url.
The site collection url would become "http://www.mysite.com/sites/site1" the server relative url of te report would be "/sites/site1/my reports/report1.rdl". Put them together
http://www.mysite.com/sites/site1/sites/site1/My Reports/Report1.rdl - ooops
To fix this I created a web part to act as a proxy between the ListView web part and the RS Viewer WebPart.
Code
using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.ComponentModel;
using System.Data;
using System.Collections.Generic;
public class MyWebPart : System.Web.UI.WebControls.WebParts.WebPart, IWebPartRow
{
Queue callbackQueue = new Queue();
object rowData;
PropertyDescriptorCollection rowSchema;
public MyWebPart()
{
this.ExportMode = WebPartExportMode.All;
}
protected override void CreateChildControls()
{
return;
}
[ConnectionConsumer("AttrReportPathRowConsumer", "ReportDefinition", AllowsMultipleConnections = false)]
public void SetRowProvider(IWebPartRow reportPathProvider)
{
if (reportPathProvider != null)
{
reportPathProvider.GetRowData(new RowCallback(this.OnReportPathFromProvider));
}
}
[ConnectionProvider("Row", "blagh", typeof(DataFormProviderConnectionPoint), AllowsMultipleConnections = true)]
public IWebPartRow GetProviderInterface()
{
return this;
}
protected override void RenderContents(HtmlTextWriter writer)
{
if (this.rowData != null)
{
DataRowView view = this.rowData as DataRowView;
if (view != null)
{
int index = view.Row.Table.Columns.IndexOf("DocUrl");
if (index != -1)
{
writer.Write(view.Row.ItemArray[index].ToString());
}
}
}
}
private void OnReportPathFromProvider(object rowData)
{
DataRowView view = rowData as DataRowView;
if (((view != null) && (view.Row != null)) && ((view.Row.ItemArray != null) && (view.Row.ItemArray.Length > 0)))
{
int index = view.Row.Table.Columns.IndexOf("DocUrl");
if (index != -1)
{
if (!SPContext.Current.Site.ServerRelativeUrl.Equals("/"))
{
string url = SPContext.Current.Web.Site.ServerRelativeUrl;
string serverRelativeReportPathUrl = view.Row.ItemArray[index].ToString();
string siteRelativeReportPathUrl = serverRelativeReportPathUrl.Remove(0, url.Length);
view.Row[index] = siteRelativeReportPathUrl;
view.Row.AcceptChanges();
}
}
}
this.rowData = view;
this.rowSchema = null;
sendRow();
}
private void sendRow()
{
while (callbackQueue.Count > 0)
{
RowCallback callback = callbackQueue.Dequeue();
callback(this.rowData);
}
}
#region IWebPartRow Members
void IWebPartRow.GetRowData(RowCallback callback)
{
if (this.rowData != null)
{
callback(this.rowData);
}
else
{
callbackQueue.Enqueue(callback);
}
}
PropertyDescriptorCollection IWebPartRow.Schema
{
get
{
if (this.rowSchema == null)
{
try
{
this.rowSchema = TypeDescriptor.GetProperties(this.rowData);
}
catch (Exception)
{
return new PropertyDescriptorCollection(null);
}
}
return this.rowSchema;
}
}
#endregion
}