Comment refaire une interface visuelle par dessus Reporting Services en utilisant les services Web

Par défaut, Reporting Services offre deux modes de fonctionnement:

  1. Natif où il utilise HTTP.SYS comme serveur Web et fournit son propre portail;
  2. Intégré à SharePoint où il utilise IIS comme serveur Web et SharePoint comme portail.

Visuellement, la plus grande différence est au niveau de l’apparence et la disposition des paramètres.

En mode natif, les paramètres s’affichent en haut de la barre d’outils, deux paramètres par ligne:

image

En mode intégré, ils s’affichent à droite de la page, un en dessous de l’autre.

image

Pour le reste, le rapport en soi ne change pas.

Que faire alors si vous désirez changer dramatiquement l’apparence générale (barre d’outils, paramètres) et quand même profiter de de Reporting Services afin de générer le rapport?

Peut-être que vous voulez développer une interface Web mieux adapté à l’apparence générale de votre application. Ou peut-être voulez-vous développer une application mobile sous iOS, Android etc.

Idéalement, pour un rapport donné, il serait possible d’obtenir la liste des paramètres avec leur définition et la dépendance entre eux. À partir de celle-ci, il serait possible de construire une interface graphique spécifique permettant à l’utilisateur de choisir des valeurs. Grâce à la définition des dépendances, il serait possible pour l’application de rafraîchir les listes de choix dépendantes lors d’un changement.

Et bien il se trouve qu’en utilisant le service Web ReportService2006.ReportingService2006 il est possible d’obtenir la définition complète des paramètres via la méthode GetReportParameters.

Ensuite, il est possible de lancer l’exécution d’un rapport SSRS via ReportExecution2005.ReportExecutionService ou tout simplement en construisant une requête HTTP POST vers le Report Server.

Si vous êtres dans un environnement C# (ex. ASP.Net MVC), il est très facile de générer un proxy vers les services Web et d’utiliser les classes ReportParameter, ValidValue directement dans l’application “client” du service Web.

Si par contre vous travaillez en Objective C sous iOS, il serait peut-être plus simple de retourner la définition complète des paramètres en XML. Dans ce cas, il suffit de vous créer (du côté serveur), un point d’entrée vous permettant de faire appel à GetReportParameters et à sérialiser le résultat en XML:


  public string GetReportParametersXml(string sReportUrl, string sHistoryID, ReportService2006.ParameterValue[] apValues,
                                         ReportService2006.DataSourceCredentials[] apDSCredentials)
    {
      ReportService2006.ReportParameter[] apParams = this.GetReportParameters(sReportUrl, sHistoryID, apValues, apDSCredentials);
      XmlSerializerNamespaces pNS = new XmlSerializerNamespaces();
      pNS.Add("", "");
      string sResult = SerializeObject(apParams, Encoding.GetEncoding("ISO-8859-1"), pNS, false);
      sResult = sResult.Replace(" xmlns=\"http://schemas.microsoft.com/sqlserver/2006/03/15/reporting/reportingservices\"", "");
      return sResult.Replace("", "");
    }
  private static string SerializeObject(object pObjectToSerialize, Encoding pEncoding, XmlSerializerNamespaces pNS, bool bOmitXmlDeclaration)
    {
      XmlSerializer pSerializer = new XmlSerializer(pObjectToSerialize.GetType());
      MemoryStream pMS = new MemoryStream();
      XmlWriterSettings pSettings = new XmlWriterSettings();
      pSettings.Indent = true;
      pSettings.OmitXmlDeclaration = bOmitXmlDeclaration;
      pSettings.Encoding = pEncoding;
      XmlWriter pWriter = XmlWriter.Create(pMS, pSettings);
      pSerializer.Serialize(pWriter, pObjectToSerialize, pNS);
      return pEncoding.GetString(pMS.ToArray());
    }

Cela vous donne toute l’information nécessaire pour construire dynamiquement votre interface de saisie de paramètres. Par la suite, vous devez donner un moyen à l’utilisateur de soumettre sa sélection afin de rafraîchir le rapport avec les nouvelles valeurs.

Lors du changement de la valeur d’un paramètre, il se peut que cela affecte les valeurs acceptées pour un autre paramètres (ex. Catégorie, Sous-Catégorie, Produit). Il vous faudra donc détecter les changements de valeurs, vérifier si un ou plusieurs paramètres sont dépendants et les rafraîchir au besoin. Il suffit de rappeler GetReportParameters en fournissant des valeurs dans le paramètre ParameterValue[] values et d’aller chercher les nouvelles valeurs valides (<ValidValues><ValidValue> …) pour ces paramètres dépendants.

Il reste un seul problème: Reporting Services ne peut pas faire de magie pour identifier les dépendances entre les paramètres. Comme il ne nous permet pas d’exprimer explicitement ces dépendances, il tente de les déduire. Si vous utilisez des expressions complexes (concaténation ou appel de fonction) pour obtenir la requête, il ne peut pas l’interpréter et place tous les paramètres précédents comme dépendance ce qui est faux 99% du temps.

Une piste de solution pour alléger le problème serait d’utiliser les paramètres avancés des paramètres et d’employer “Never Refresh” sur ceux qui ne dépendent pas d’autres paramètres que l’utilisateur peut changer.

clip_image001

Dans le XML, la valeur de cette option prendra cette forme: <UsedInQuery>False</UsedInQuery>. Si le noeud est absent, c’est Auto et “Always Refresh” équivaut à <UsedInQuery>False</UsedInQuery>.

Lorsqu’on construit la liste des paramètres à rafraîchir suite à un changement de valeur, il faut exclure ceux qui sont marqués avec « Never Refresh » même si le paramètre qui a changé est dans leur liste de dépendances.

Vous voilà mieux informé sur ce qui est possible de faire avec les services Web de Reporting Services dans le contexte d’une application souhaitant utiliser sa propre mécanique pour la saisie de paramètres.

N’hésitez pas à commenter,

Un commentaire sur “Comment refaire une interface visuelle par dessus Reporting Services en utilisant les services Web

Laisser un commentaire