Naši partneři
BMI SYSTEM CZECH
Informační systémy budoucnosti

ReportViewer a AJAX - zajímavý problém


Nasazení SSRS

Svými spořivými zákazníky jsem byl "donucen" udělat hodně muziky za málo peněz, a jedna z věcí, která se - podle mého - povedla, bylo vyždímání Microsoft SQL Server 2008 Express Edition with Advanced Features.

 

Ty "Advanced Features" znamenají, že vývojář má zadarmo k dispozici omezenou, ale přesto nějakou verzi Reporting Services. Omezení znamenají zejména nemožnost plánování reportů, jejich odesílání apod., ale na vytvoření ad-hoc reportu krásně stačí, a podporují i pěkné formáty exportu reportů (např. PDF).

 
Jak dostat report do svého webu

Reporting Services (zkráceně SSRS) jsou serverovou technologií, a jejich hlavním úkolem je reporty generovat. K prohlížení reportů lze využít Report Manager - web, který ale slouží hlavně k administraci obsahu SSRS, pro uživatele už tak pěkný není, mimo jiné proto, protože asi málokomu padne do designu aplikací, a navíc je anglicky.

 

Součástí webu SSRS jsou ale také webvé služby, nebo možnost "vyvolat" report pomocí odkazu odjinud. Ta druhá možnost (pomocí odkazu) je využívána komponentou ReportViewer. ReportViewer pro ASP.NET je objekt obsažený v namespace "Microsoft.Reporting.WebForms", ale existuje i Windows Form obdoba, která funguje prakticky stejně.

 

Než začneme implementovat, musíme mít nainstalován a nakonfigurován ReportViewer ve web.config webu. Pro instalaci je třeba najít soubor "ReportViewer.exe" (na instalační cestě Visual Studia), tento soubor se pak spustí na webovém serveru (není nutno, když databáze a web jedno jsou - FUJ!).

 

Assembly je ve web.config registrována pomocí klasického HttpHandleru (IIS 6), nebo pomocí modulů (IIS 7).

 

Poslední, co je třeba udělat, je vytvořit webovou stránku v ASP.NET.

 
ASP.NET stránka s objektem ReportViewer

Asi není třeba dlouze něco popisovat, následují kousky stránky:

 

Direktiva v záhlaví:

<%@ Register Assembly="Microsoft.ReportViewer.WebForms, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %>

 

Užití komponenty ReportViewer - důležité je vypnutí AsyncRendering (pak se report sice načte, ale radši se neukáže - zapnutý AsyncRendering se projeví tím, že se ukazuje takové to zelené kolečko "report is being generated"), dále vypnutí parametrů a tlačítek (jsou anglicky, formulář pro zadávání parametrů je vyroben vlastnoručně, s vlastními kontrolami, a česky), a nakonec (a jak se ukáže, i nejdůležitější) je nastavení reportu na Visible="false":

 

<rsweb:ReportViewer ID="rsPoctyProduktu" runat="server"

Height="100%" ProcessingMode="Remote" Width="100%" AsyncRendering="false"

ShowParameterPrompts="false" ShowBackButton="false" ShowFindControls="false" ShowRefreshButton="false" Visible="false">

</rsweb:ReportViewer>

 

Kousek Code Behind - v něm jsou v komentářích "háčky", které to celé má, a pod nimi kód, který je řeší:

 

protected void btnOdeslat_Click(object sender, EventArgs e)

{

//pripojeni k ceste report serveru: http://mujserver/reports

rsPoctyProduktu.ServerReport.ReportServerUrl = ReportServerUrl;

//prvni bug - problem s tim, ze se musi "resetovat" drill through

while (this.rsPoctyProduktu.ServerReport.IsDrillthroughReport)

{

this.rsPoctyProduktu.PerformBack();

}

//uzivatel a nastaveni cesty k reportu

rsPoctyProduktu.ServerReport.ReportServerCredentials = new RsUzivatel();

rsPoctyProduktu.ServerReport.ReportPath = "/slozka/nazevReportu";

//nastaveni parametru

DateTime datum = DateTime.MinValue;

DateTime.TryParse(txtDatumOd.Text, out datum);

string dOd = datum.Year.ToString() + "-" + datum.Month.ToString() + "-" + datum.Day.ToString();

DateTime.TryParse(txtDatumDo.Text, out datum);

string dDo = datum.Year.ToString() + "-" + datum.Month.ToString() + "-" + datum.Day.ToString();

ReportParameter dtOd = new ReportParameter("datumOd", dOd);

ReportParameter dtDo = new ReportParameter("datumDo", dDo);

rsPoctyProduktu.ServerReport.SetParameters(new ReportParameter[] { dtOd, dtDo });

//dalsi bug - koexistence s AJAXem

rsPoctyProduktu.Visible = true;

//nacteni

rsPoctyProduktu.ServerReport.Refresh();

}

Dost důležité ještě je popsat objekt RsUzivatel. Když budeme z ASP.NET stránky přistupovat na report umístěný na SSRS, musíme se nějak přihlásit. Při přihlášení nestačí Report Serveru klasické credentials, musí mít svoje vlastní (resp. takové credentials, které pochopí). To se dělá tak, že si vytvoříte třídu, do které implementujete rozhraní

Reporting.WebForms.IReportServerCredentials

Tento interface toho moc po vás chtít nebude, v podstatě všechno, co předepíše může být null, jediná vlastnost, která se určitě musí nastavit, je read-only vlastnost NetworkCredentials.

 
Rekapitulace zjištěných problémů

Předchozí úryvky kódu už obsahují řešení všech problémů, na které jsem narazil, ale přesto stojí za to si okomentovat, co jsme to vlastně řešili.

 

První zajímavostí je, že když si necháme krásně zobrazit zelené kolečko "počkejte, generuji", tak se samotný report nezobrazí. To léčí právě vypnutí vlastnosti AsyncRendering.

 

Velmi podobné symptomy měl i problém, kvůli kterému byla do kódu pro načtení reportu vložena smyčka okomentovaná jako "první bug".

 

Do třetice, a asi nejhorší, byl okamžik, kdy ve formuláři, do kterého uživatelé zadávají parametry, byl vložen AJAX UpdatePanel. Konstelace AJAXu a ReportVieweru vedla k tomu, že AJAX končil chybou "parameter out of range" bez dalšího vysvětlení. Podle Microsoftu je to uznaný bug, ke kterému není ani řešení, ani "oklika" ("work around"). Nicméně jedno existuje. ReportViewer se v deklaraci na stránce "schová" (visible="false"), a pak se v kódu těsně před načtením zobrazí.

 

Pokud absolvujete všechny popsané prostocviky, uvidíte něco takového:

 
Sdílejte tuto položku se svými přáteli
 
Související články
TOPlist