Come esportare il contenuto di una istanza di Reporting Services
Migrare reporting services e' una operazione ben documentata. Oggi vedremo come, con poche righe di codice, sia possibile esportare una istanza di reporting services su file system. Non entrero' nel dettaglio di come collegarsi e utilizzare il web service di reporting services (per dettagli vedere qui: http://msdn.microsoft.com/en-us/library/bb522713.aspx). Mi limitero' a utilizzare questi due metodi che fanno al caso nostro:
Il primo metodo e' in grado di restituire tutti gli oggetti di una istanza di RS, il secondo estrae il contenuto come array di bytes. Salvando su file system il contenuto noteremo che si tratta dello stesso XML (o meglio, RDL) che compone il report.
Il codice a questo punto e' molto semplice (qui sotto ne pubblico uno spunto per una eventuale implementazione):
RS2010.ReportingService2010SoapClient svc = new RS2010.ReportingService2010SoapClient();
svc.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
svc.Endpoint.Address = new System.ServiceModel.EndpointAddress(args[0]);
RS2010.TrustedUserHeader tuh = new RS2010.TrustedUserHeader();
RS2010.CatalogItem[] items = null;
// Lettura di tutti gli oggetti del server
svc.FindItems(tuh, "/", RS2010.BooleanOperatorEnum.And,
new RS2010.Property[] { new RS2010.Property() { Name = "Recursive", Value = "true" } },
new RS2010.SearchCondition[] { },
out items);
#region Extract all
if (fExtractAll)
{
Console.WriteLine("Extracting all items");
byte[] bBuffer2;
for (int i = 0; i < items.Length; i++)
{
if (items[i] is RS2010.CatalogItem)
{
RS2010.CatalogItem ci = (RS2010.CatalogItem)items[i];
if (ci.TypeName == "Folder")
continue;
try
{
Console.WriteLine("Extracting " + ci.Path);
// Estrazione definizione dell'oggetto
svc.GetItemDefinition(tuh, ci.Path, out bBuffer2);
int idx = ci.Path.LastIndexOf('/');
string strPath = ci.Path;
if (idx > 0)
{
strPath = strPath.Substring(0, idx);
strPath = strPath.Replace('/', System.IO.Path.DirectorySeparatorChar).Substring(1);
}
else
{
strPath = "";
}
System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(
strBaseDirectory + System.IO.Path.DirectorySeparatorChar +
strPath);
if (!di.Exists)
di.Create();
string strFileName = di.FullName + System.IO.Path.DirectorySeparatorChar + ci.Name;
if (ci.TypeName == "Report")
strFileName += ".rdl";
else
strFileName += ".xml";
using (System.IO.FileStream fs = new System.IO.FileStream(
strFileName,
System.IO.FileMode.Create,
System.IO.FileAccess.ReadWrite,
System.IO.FileShare.Read))
{
fs.Write(bBuffer2, 0, bBuffer2.Length);
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
#endregion
Un paio di note:
- Ricordatevi di alzare il valore maxReceivedMessageSize del binding al WS.
- Per usare l'autenticazione integrata impostate security mode="TransportCredentialOnly " e transport clientCredentialType="Windows".
- Benche' sia possibile esportare anche i shared data sources, fate attenzione perche' le password non verranno esportate.
Happy coding,
Francesco Cogno
Comments
- Anonymous
December 26, 2011
Se non si vuole scrivere codice, è possibile usare il Reporting Services Scripting Tool: www.sqldbatips.com/showarticle.asp Free e veramente ottimo