SSRS 2008 : Générer des rapports Reporting Services multi-langues (localisation)

by ygremillon 15. février 2012 20:13
Actuellement, le multi-langues dans un rapport Reporting Services peut être géré de plusieurs façons :
  • Créer un modèle de rapport par langue. C’est la méthode la plus simple, mais elle peut devenir très contraignante s’il y a un nombre importants de rapports / langues à traiter.
  • Gérer les libellés dans la base de données.
  • Utiliser la Globalisation / Localisation du Framework .NET via une librairie de ressources.
Nous allons nous intéresser à cette dernière méthode.
En premier lieu, nous allons créer la librairie de ressources.
Dans Visual Studio, nous créons un nouveau projet de librairie de classes.
On ajoute nos fichiers de ressources au projet. Pour mon exemple, le fichier de ressources se nomme : Localization.resx
On ajoute ensuite une nouvelle classe au projet, contenant le code ci-dessous :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

    public static class LocalizedValue
    {
        public static string GetString(string cultureInfo, string resource, params object[] args)
        {
            CultureInfo ci = new CultureInfo(cultureInfo);
            string s = Localization.ResourceManager.GetString(resource, ci);
            if (args != null && args.Count() > 0)
                return string.Format(ci, s, args);
            else
                return s;
        }
    }
Une fois le projet compilé, il est nécessaire de copier l’ensemble des DLLs générées (le fichier de base et les fichiers de langues) sur le serveur SSRS.
Pour le designer (Visual Studio), les fichiers doivent être copiés dans le répertoire :
C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies
Pour le serveur de reporting, les fichiers doivent être copiés dans le répertoire :
C:\Program Files\Microsoft SQL Server\MSRS.10.MonServeur\Reporting Services\ReportServer\bin
Coté rapport, notre DLL doit être référencée pour pouvoir être utilisée.
Pour cela, dans le menu « Report », on sélectionne « Report Properties » puis l’onglet « References ». Enfin, on ajoute la DLL de ressources.
Ensuite, il suffit d’ajouter l’expression suivante dans une TextBox. 
=MyLibrary.LocalizedValue.GetString(User!Language, "MaRessource")
MyLibrary est l’espace de noms définit par ma DDL de ressources (par défaut, le nom de la DLL).
LocalizedValue est le nom de la classe statique que l’on souhaite utiliser.
GetString est le nom de la méthode que l’on a défini précédemment.
User!Language est une variable prédéfinie par SSRS. Il s’agit d’une chaine de caractères contenant le code de la culture (fr-FR, en-US, …)
MaRessource est la clé de ma ressource
 

Tags: ,

Développement

Le taux d’adoption du Cloud Computing par les entreprises est plus fort en France qu’ailleurs en Europe

by Philippe Limantour 11. janvier 2012 20:29

La France est en avance dans l'adoption du Cloud Computing !
La croissance du marché Cloud en France a éé de +61% en 2011 passant à 846 millions d'euros, selon la dernière étude IDC.

 Les entreprises sont pragmatiques :

  • Le Cloud Computing est analysé comme un modèle de delivery à part entière par les entreprises. Celle-ci n'ont pas d'idées préconçues et privilégient le pragmatisme, en étudiant ce modèle selon des critères qui gouvernent l'entreprise (budget / performance / sécurité). Ce type de comportement fait le jeu des approches hybrides, avec 43% des entreprises qui privilégient ce modèle
  • A seulement 7%, la part des entreprises excluant le Cloud Computing, qu'il soit public ou privé, est faible, ce qui laisse envisager un taux de pénétration potentiel important. Les entreprises sont ainsi 78% à prévoir d'inclure au moins un service Cloud dans leur prochain contrat d'outsourcing, qu'il soit nouveau ou renouvelé.

Des attentes précises :
 
Selon les technologies évaluées ou retenues, les problématiques identifiées par les entreprises ressortent nettement:

  • Sécurité, localisation des données, manque d'auditabilité, réversibilité et intégration pour le Cloud public
  • Manque de financement, manque de compétences internes, résistance au changement ou gouvernance pour le Cloud privé.

Le Cloud public sera le modèle qui se développera le plus massivement à l'avenir (compte tenu des investissements déployés, de son potentiel de distribution, de ses coûts et de ses fonctionnalités).

La plateforme PaaS Microsoft Azure est à ce compte la solution se développant le plus rapidement, permettant d'industrialiser le développement, le test de montée en charges, et la production de solutions métiers, tout en offrant des fonctionnalités avancées de couplage avec les environnements internes à l'entreprise (synchronisation des annuaires, fédération des identités, accès aux données locales via le Service Bus, etc.)

Tags: , , ,

Cloud | Innovation

Office 365 devient le premier service majeur de productivité accessible via le Cloud à suivre les règles européennes en matière de protection et de sécurité des données à caractère personnel

by Philippe Limantour 19. décembre 2011 22:28

Office 365 devient le premier service majeur de productivité accessible via le Cloud à suivre les règles européennes et américaines en matière de protection et de sécurité des données à caractère personnel

Microsoft annonce des améliorations dans les mesures de sécurité et de protection de la vie privée mises en place dans Office 365

 
Microsoft Corp. annonce qu’Office 365, son service de nouvelle génération proposant des outils de productivité via le Cloud, est la première plate-forme d’envergure hébergée dans le Cloud à proposer des mesures de sécurité et de protection de la vie privée fortes pour les clients exerçant leur activité dans l’Union européenne et aux Etats-Unis. Dans le cadre de son engagement contractuel envers ses clients, Microsoft signera désormais les Clauses Contractuelles Types, qui permettront aux clients de s’assurer qu’ils se conforment à la Directive sur la protection des données à caractère personnel, et respectera les dispositions de la loi américaine Health Insurance Portability and Accountability Act (HIPAA).
Microsoft annonce également le lancement du site Internet Trust Center Office 365. Ce site fournit des informations approfondies sur les pratiques de sécurité et de confidentialité d’Office 365 et a subi récemment d’importants changements de conception visant à le rendre plus accessible et plus facile à comprendre. Le nouveau site est accessible à l’adresse suivante : http://trust.office365.com.

 

Mises à jour en matière de conformité

 

En février 2010, l’Union européenne a adopté des clauses contractuelles (plus connues sous le nom de « Clauses Contractuelles Types ») visant à fournir un cadre juridique au transfert de données à caractère personnel via des réseaux internationaux vers des pays situés en dehors de l’Espace Économique Européen (EEE). Lorsqu’elles sont incluses dans des contrats de prestations de services conclus avec des sous-traitants, les Clauses Contractuelles Types assurent aux clients que les mesures appropriées ont été prises afin de protéger les données à caractère personnel, quand bien même celles-ci seraient stockées dans un centre hébergeant des services de Cloud situé en dehors de l’EEE. Les autorités de contrôle européennes ont la possibilité de demander que les clients cessent toute utilisation d’un service qui n’aurait pas pris toutes les mesures requises afin de protéger les données à caractère personnel et ce, jusqu’à ce qu’elles aient procédé à un contrôle du service concerné et jugé qu’il se conformait aux règles européennes en matière de protection et de sécurité des données.

Outre l’utilisation des Clauses Contractuelles Types, Microsoft est allé plus loin que d’autres fournisseurs de services de Cloud en incluant un accord relatif au traitement des données pour les clients européens. Certains des 27 États Membres ont des exigences plus strictes que les dispositions de la Directive européenne sur la protection des données à caractère personnel. Pour rationaliser les services hébergés dans le Cloud pour les clients soumis à des obligations de conformité supplémentaires, Microsoft a prévu, outre les Clauses Contractuelles Types, un solide contrat relatif au traitement des données élaboré en tenant compte des particularités des règlementations de chaque État Membre.
 
« Le développement d’outils de productivité hébergés dans le Cloud qui répondent aux attentes des entreprises européennes représente bien plus que la simple conception d’applications sur un navigateur » a déclaré Jean-Philippe Courtois, Président de Microsoft International. « En matière de sécurité et de protection des données, Microsoft développe une approche des lois européennes plus complète que toute autre société, et nous sommes fiers du travail que nous avons accompli afin de veiller à ce que la plus large gamme d’organisations puisse passer au Cloud en toute confiance – ou opter pour une formule sur site tout aussi fonctionnelle ».
En tant que premier service majeur de productivité hébergé dans le cloud à obtenir la certification ISO/IEC 27001 - une norme internationale de système de gestion de la sécurité de l'information - Microsoft mandate, chaque année, un expert indépendant afin qu’il procède à un audit de sa politique en matière de sécurité de l’information et communique les résultats à ses clients. Par ailleurs, Microsoft a conçu ses services en ligne afin de fournir des mesures de protection physique, administrative et techniques qui permettent de se conformer totalement aux dispositions de la loi HIPAA.
 
« Jusqu’à récemment, certaines préoccupations concernant la sécurité et la confidentialité des données des patients représentaient l’obstacle le plus courant des organisations du secteur de la santé bénéficiant de tout le potentiel de leurs technologies hébergées dans le Cloud » a déclaré Michael Robinson, General Manager for U.S. Health and Life Sciences chez Microsoft. « Microsoft contribue à la suppression de cet obstacle en intégrant des fonctionnalités de confidentialité et de sécurité dans Office 365 qui permettent aux organisations du secteur de la santé de répondre aux obligations de conformité prévues par la loi HIPAA. A ce jour, Office 365 peut aider des hôpitaux, des assureurs et des cliniques à donner aux membres de leur personnel les moyens d’être efficaces et productifs, en toute confidentialité, à tout moment, en tout lieu, tout en réduisant considérablement leurs frais d’exploitation liés aux technologies de l’information ».

 

Concernant Office 365

 
Office 365 regroupe Microsoft Office, Microsoft SharePoint Online, Microsoft Exchange Online et Microsoft Lync Online au sein d’un service de Cloud constamment actualisé. Avec Office 365, le passage au Cloud n’entraine aucun changement dans les méthodes de travail car ce système repose sur des outils de productivité de pointe auxquels les gens sont habitués, qu’ils connaissent et en lesquels ils ont confiance. Les utilisateurs ont ainsi de nouveaux moyens leur permettant de travailler ensemble, facilement, sur pratiquement tout dispositif ou téléphone mobile, en utilisant des applications qui leur sont familières, telle qu’Office, qu’ils connaissent déjà et qu’ils apprécient. Le Cloud offre aux dirigeants de société la fiabilité, les mesures de sécurité et les contrôles informatiques dont ils ont besoin.
Pour toute information sur Office 365 veuillez consulter le site situé à l’adresse suivante : http://www.neos-sdi.com/fr/solutions-microsoft-et-ecosysteme/office-365/

Tags: ,

Cloud | Collaboratif | SharePoint

Développement applicative avec une base de donnée Oracle sans l'installation du client

by Charles BARJANSKY 7. novembre 2011 22:39
Le développement d'une application .Net pour un environnement Web ou Windows avec une plateforme Oracle était jusqu'à récemment problématique car il nécessitait l'installation du client Oracle sur l'environnement de développement et l'environnement finale (poste client et/ou serveur).
 
Dorénavant, la librairie Oracle ODP .NET requiert, au minimum, la présence des DLL suivantes dans l'environnement d'exécution de l'application:
  • Oracle.DataAccess.dll (ODP .NET)
  • OraOps11w.dll (DLL d'interface avec Instant Client)
  • oci.dll (Instant Client)
  • oraociicus11.dll (Instant Client)
Vous pouvez récupérer ces DLL dans l'archive "ODAC with Xcopy Deployment" sur le site d'Oracle.
Ainsi vous pouvez simplement ajouter ces fichiers dans le dossier d'exécution de l'application pour permettre le bon fonctionnement de celui-ci.

Je vous recommande bien entendu de "clarifier" ce processus. Il existe plusieurs façons d'y procéder et je vous propose la suivante:
  • Ajouter un dossier "Libraries" à votre solution
  • Copier les DLL citées ci-dessus
  • Ajouter les commandes suivantes à votre projet UI dans la liste des commandes à exécuter lors de la compilation (Project "Properties" -> "Build Events" tab -> "Post-build event command line" textbox)
xcopy "$(SolutionDir)Libraries\oci.dll" "$(TargetDir)"
xcopy "$(SolutionDir)Libraries\Oracle.DataAccess.dll" "$(TargetDir)"
xcopy "$(SolutionDir)Libraries\oraociicus11.dll" "$(TargetDir)"
xcopy "$(SolutionDir)Libraries\OraOps11w.dll" "$(TargetDir)"
Si vous avez un projet de package, veillez à ne pas les omettre de la liste des fichiers présents dans le dossier de l'application ("Application Folder" ou "Web Application Folder\bin").
 
Charles

Tags:

Développement

Déploiement et distribution du modèle objet client de SharePoint 2010

by Franck Musson 20. octobre 2011 02:35

Pour utiliser le modèle objet client de SharePoint 2010 sur une machine sur laquelle ne sont pas installés les binaires de SharePoint 2010,

il y a un petit download a réaliser : http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=21786

il vous sera alors possible d'écrire du code distant interagissant avec les web services de SharePoint

Example

using (SP.ClientContext ctx = new SP.ClientContext("http://sharepoint2010"))
            {
                SP.FormsAuthenticationLoginInfo formsLoginInfo = new SP.FormsAuthenticationLoginInfo();
                ctx.AuthenticationMode = SP.ClientAuthenticationMode.Default;
                // ctx.FormsAuthenticationLoginInfo = formsLoginInfo;

                SP.List list = ctx.Web.Lists.GetByTitle(lst);
                try
                {
                    list = ctx.Web.Lists.GetByTitle(lst);
                    SP.ListItemCreationInformation itemCreateInfo = new SP.ListItemCreationInformation();
                    SP.ListItem listItem = list.AddItem(itemCreateInfo);
                    listItem["Title"] = "Réservation N° : " + bookingid.ToString()+" le "+flightdate.ToShortDateString();
                    listItem["CustomerID"] = customerid;
                    listItem["BookingID"] = bookingid;
                    listItem.Update();
                    ctx.ExecuteQuery();
                }
                catch (SP.ServerException)
                {
                    list = null;
                }

etc...

Tags: ,

SharePoint

Fusionner plusieurs fichiers XPS

by Gilles DEHAIS 8. octobre 2011 00:23

Les fichiers XPS sont un peu l'équivalent du PDF mais version Microsoft. En effet, ce type de fichier permet l'impression d'un document avec un rendu équivalent que ça soit sur différents ordinateurs et/ou imprimantes. Il permet aussi de bloquer l'édition puisqu'un fichier XPS n'est pas éditable. Il s'agit d'une "image" des pages du document d'origine.

Cependant, il se peut que vous ayez à fusionner plusieurs fichiers XPS pour obtenir un seul fichier final. Nous allons voir que cela est possible avec quelques lignes de codes et grâce à l'API Document qui contient l'API XPS.

 

Tout d'abord, il faut créer notre fichier final qui sera la fusion de nos différents fichiers XPS.

 

dstPackage = Package.Open(dstMergedXpsFileName, FileMode.Create);
dstMergedXps = new XpsDocument(dstPackage);
FixedDocumentSequence dstDocumentSequence = new FixedDocumentSequence();
xpsWriter = XpsDocument.CreateXpsDocumentWriter(dstMergedXps);

 

On utilise l'objet Package pour créer notre fichier sur le disque dur puis nous créons notre document XPS qui contiendra la séquence des documents (nos différentes pages). Un DocumentWriter est aussi nécessaire pour pouvoir remplir notre fichier XPS et l'enregistrer.

Maintenant que notre document final est prêt à recevoir les pages des documents XPS que l'on souhaite fusionner, il suffit d'ouvrir chacun de ces documents, en récupérer les pages (leurs références) et les ajouter dans notre document final les uns après les autres.

 

srcXps = new XpsDocument(srcXpsFileName, FileAccess.Read);
FixedDocumentSequence srcDocumentSequence = srcXps.GetFixedDocumentSequence();
DocumentPaginator DocPager = srcDocumentSequence.DocumentPaginator;
printTickets.Add(srcXps.FixedDocumentSequenceReader.PrintTicket);
foreach (DocumentReference srcReference in srcDocumentSequence.References)
{
     DocumentReference dstReference = new DocumentReference();
     (dstReference as IUriContext).BaseUri = (srcReference as IUriContext).BaseUri;
     dstReference.Source = srcReference.Source;
     dstDocumentSequence.References.Add(dstReference);
}

 

Comme décrit dans le code ci-dessus, on ouvre notre document, on récupère sa séquence de pages (FixedDocumentSequence) puis pour chaque page, on ajoute une référence (DocumentReference) à notre fichier final, son adresse (sa localisation dans le fichier XPS qui n'est en faite qu'un fichier ZIP) et sa source qui est notre page en elle même.

On peut voir aussi la notion de "PrintTicket". Les "PrintTicket" dans les fichiers XPS permettent de définir si la page est en mode portrait ou paysage. Ainsi, l'imprimante pourra imprimer certaines pages en mode paysage tandis que d'autres le seront en mode portrait.

Enfin, il ne nous reste plus qu'à sauvegarder notre fichier final après avoir fusionner tous nos fichiers. Ceci se fait de la manière suivante :

 

xpsWriter.Write(dstDocumentSequence);
dstMergedXps.Close();
dstPackage.Close();

 

Voilà, notre fichier contient maintenant toutes les pages des fichiers que l'on souhaitait fusionner en un seul. Il reste cependant un petit bémol à la fusion de fichiers XPS. Ainsi, si vous avez une pagination dans chacun de vos fichiers, cette pagination n'est pas modifiée car une page dans un fichier XPS ne peut être modifiée car elle est devenu une "image". Vous pouvez modifier l'extension de vos fichiers XPS et la renommer en ".zip" pour découvrir l'architecture complète d'un fichier XPS.

Je vous joins à cette article le code source.

FusionXPS.zip (30,07 kb)

Tags:

Récupérer le nom des jobs relatifs aux abonnements Reporting Services.

by Olivier Moreau 5. octobre 2011 23:17

Le code SQL ci-dessous permet de retrouver les noms des jobs des abonnements Reporting Services.
Code bien utile quand on doit retrouver un abonnement parmi des centaines pour le rejouer à la demande.

Script pour le rejouer :

EXEC msdb..sp_start_job 'GUID DU JOB'

 

Script pour retrouver le job :

SELECT 
	ReportSchedule.ScheduleID AS JOB
	,CATALOG.Name AS Nom_Rapport
	, Subscriptions.Description AS Description
	, Subscriptions.LastStatus as Statut_Abonnement
	, Subscriptions.LastRunTime as Derniere_Execution
FROM 
	CATALOG
		JOIN Subscriptions  ON CATALOG.ItemID = Subscriptions.Report_OID
		JOIN ReportSchedule ON CATALOG.ItemID = ReportSchedule.ReportID
							AND ReportSchedule.SubscriptionID = Subscriptions.SubscriptionID
ORDER BY 	
	CATALOG.Name,
	ReportSchedule.ScheduleID

Tags:

Business Intelligence

Script SQL : arrondi au quart d'heure

by Olivier Moreau 19. septembre 2011 19:04

Voici un script SQL qui permet d'arrondir une date au quart d'heure le plus proche

DECLARE @MADATE AS DATETIME
SET @MADATE = '01/01/2011 10:07:29'
SELECT cast(round((cast(@MADATE as float(53))*24*4),0)/(24*4) as smalldatetime)

Résultat : 2011-01-01 10:00:00

SET @MADATE = '01/01/2011 10:07:30'
SELECT cast(round((cast(@MADATE as float(53))*24*4),0)/(24*4) as smalldatetime)

Résultat : 2011-01-01 10:15:00

 

Pour arrondir systématiquement au quart d'heure inférieur on utilisera la fonction FLOOR à la place de ROUND

DECLARE @MADATE AS DATETIME SET @MADATE = '01/01/2011 10:07:29'
SELECT cast(floor(cast(@MADATE as float(53))*24*4)/(24*4) as smalldatetime)

Résultat : 2011-01-01 10:00:00

SET @MADATE = '01/01/2011 10:14:30'
SELECT cast(floor(cast(@MADATE as float(53))*24*4)/(24*4) as smalldatetime)

Résultat : 2011-01-01 10:00:00

Tags:

Business Intelligence

Lancer un processus asynchrone en Asp.Net

by Gilles DEHAIS 11. juillet 2011 20:46

Bonjour,

Nous allons voir comment lancer un processus de façon asynchrone en ASP.Net. En effet, vous vous êtes surement retrouver devant le cas d'une page qui doit lancer un processus relativement long (plusieurs minutes) et qui bloque alors la page Web en attendant que ce processus finisse et que le serveur réponde que l'opération s'est déroulée avec succès ou non.

Or, lorsque l'on clique sur le bouton qui lance ce processus sur le serveur, la page est comme "frisée" et les animations permettant d'indiquer à l'utilisateur d'attendre sont elles aussi figées. Heureusement, il existe un moyen de contourner ce problème : l'asynchrone.

Créer un site Asp.Net vide sous Visual Studio et ajoutez-y un autre page Web que l'on nommera "Default2.aspx". Nous allons maintenant éditer la page "Default.aspx" pour y ajouter du code javascript et nos éléments Web.

 

<title> Untitled Page </title> 
<script type="text/javascript"> 
 
    function ClientCallbackFunction(arg, ctx) {
        if (arg != "") {
            window.location = "Default2.aspx";
        }
    } 
</script>  
</head>


<body> 
 
<form id="form1" runat="server"> 
<div>
Async Callback
<br />
<asp:TextBox ID="tbxLongProcessArgs" runat="server" />
<br />
<input type="button" value="Start" id="bttAsync"
       onclick="javascript:document.all.Message.innerText='Process started';return DoTheCallback(document.all.tbxLongProcessArgs.value,1);" />
<br />
<span id="Message"></span>
</div>
</form>
</body>

 

Comme vous pouvez le constater, le bouton affiche le message 'Process started' et lance notre processus en mode asynchrone en lui donnant un argument lorsque l'utilisateur cliquera dessus. La fonction JavaScript 'ClientCallbackFunction' sera appelée lorsque notre processus sera terminé et permettra de passer sur notre 2ème page Web.  Maintenant nous allons éditer notre page Default2.aspx

 

<body>
    <form id="form1" runat="server">
    <div>
        <asp:TextBox ID="txtDesc" runat="server" Width="250px" TextMode="MultiLine"></asp:TextBox>
    </div>
    </form>
</body>

 

Cette page va nous permettre d'afficher le résultat de notre processus. Il ne nous reste plus qu'à ajouter le code behind qui lancera notre processus coûteux en temps en mode asynchrone

 

    protected void Page_Load(object sender, EventArgs e)
    {
        string js = Page.ClientScript.GetCallbackEventReference(this, "arg",
        "ClientCallbackFunction", "ctx", true);

        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        sb.Append("function DoTheCallback(arg, ctx) {");
        sb.Append(js);
        sb.Append("}");
        Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
        "callbackkey", sb.ToString(), true);
    }

Comme nous pouvons le voir, nous ajoutons à la page 'Default.aspx.cs' un évènement de type CallBack qui appelera notre fonction javascript 'ClientCallbackFunction' de notre page Default.aspx et ceci de manière totalement asynchrone. Cette évènement sera créé lorsque l'utilisateur cliquera sur le bouton 'Start' de notre page.

Maintenant, pour que la magie de l'asynchrone opère, il va falloir utiliser l'interface 'ICallbackEventHandler' que nous implémentons aussi dans notre code behind de la page Default.aspx.

 

    #region ICallbackEventHandler Members

    void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
    {
        this._eventArgument = DoLongProcess(eventArgument);
    }

    string ICallbackEventHandler.GetCallbackResult()
    {
        if (!string.IsNullOrEmpty(this._eventArgument))
            Session["errorMessageImport_P"] = this._eventArgument;
        return this._eventArgument;
    }

    #endregion

 

Lorsque l'utilisateur clique sur le bouton 'Start', notre évènement asynchrone est créé et la méthode RaiseCallbackEvent est lancée. Nous avons aussi la possibilité de lui envoyer des paramètres. C'est cette méthode qui va lancer notre processus côuteux en temps. Une fois le processus fini, la méthode GetCallbackResult est lancée et appelle la méthode javascript 'ClientCallbackFunction' de notre page. Vous pouvez utiliser des variables de Session si vous désirez sauvegarder en mémoire sur le serveur le résultat du processus.

Ainsi, une fois notre processus terminé, la page 'Default2.aspx' est appelée par le client et la réponse retournée par notre processus est affichée à l'utilisateur. Vous pouvez remarquer que lorsque vous cliquez sur le bouton 'Start', la page n'est pas figé. Elle peut donc afficher un gif animé d'attente utilisateur par exemple. 

WebSite_Async.zip (5,03 kb)

Tags:

Développement

Workshop sur HTML5 chez Microsoft

by Emmanuel Humez 28. juin 2011 20:03

Le 16 mars 2011 a eu lien au centre de conférences Microsoft un workshop sur HTML5 / CSS3 / SVG 1.1
Cette conférence a eu pour but de faire un état des lieux actuel du HTML5, de son implémentation dans les dernières versions des principaux navigateurs, des bonnes pratiques offertes par des frameworks pour faire du progressive enhancement et du fallback, sur la plateforme ASP.NET.
Le but de cet article est de vous faire un résumé rapide, et de ce que j'ai retenu de plus intéressant. Il faut souligner que cet évènement a eu lieu tout de suite après la sortie en version finale d'Internet Explorer 9. Il est aussi un prolongement d'une session des TechDays 2011 sur le même sujet.

Une norme en cours de construction

D'abord, la spécification actuelle du HTML5 par le consortium W3C est au statut "working draft" jusqu'en mai 2011. Ce n'est qu'à cette date que l'en-cours des spécifications sera en version finale, et donnera le coup d'envoi de l'adoption officielle du standard. Au départ dans la roadmap du W3C, il était prévu de livrer la version finale du HTML5 en 2022 ! C'est pourquoi en parallèle s'est constitué un groupe de travail (le WHATWG) qui rassemble des pointures de l'internet (Apple, Google, Mozilla, ... mais pas Microsoft).

Le but est de faire évoluer la norme HTML et de faire pression sur le W3C pour accélérer la roadmap et de lui faire adopter certaines fonctionnalités en standard. Le WHATWG va plus loin en prônant un HTML non versionné et évolutif. De son côté,  le W3C a donc annoncé une version finale du HTML5 en 2014.

La guéguerre des navigateurs

Les spécifications en cours du HTML5 sont l'occasion d'une compétition entre les navigateurs (Safari, Chrome, Internet Explorer, Firefox), pour imposer des éléments non encore dans la norme HTML5. A ce titre, le navigateur qui respecte le plus la norme actuelle du W3C est Internet Explorer 9 (eh oui !), s'agissant des tests effectués. En fait, Chrome et Safari (basés sur le moteur Webkit) implémentent des fonctionnalités qui ne sont pas standardisés. Le but étant de faire adopter celles-ci par le consortium, bref d'imposer des éléments actuellement propriétaires (certains se souviennent de l'époque IE6 / Netscape 4.7).
Actuellement, le risque est grand pour les développeurs de devoir re-développer des fonctionnalités basés sur des techniques dont l'évolution est instable.

Un exemple sont les WebSockets permettant la notification entre le serveur et le client ; actuellement le protocole comporte une faille de sécurité, et il n'est pas sûr que les WebSockets soient conservées sous sa forme actuelle.

Quelques nouveautés du HTML5

Plus de balises sémantiques

Le HTML5 a pour but d'offrir des nouvelles balises sémantiques, adaptées à la structure des pages web : <header>, <footer>, <nav>, <article>, <section>, <aside>, <video>, <audio>plutôt que d'avoir des <div id="header">, <div id="nav">, etc.

La page doit comporter le doctype : <!DOCTYPE html> (Une page HTML doit toujours avoir un doctype, sinon le navigateur passe en mode Quirks !)

Les balises <audio> et <video> permettent de s'affranchir des plugins de lecture. Par contre, le codec n'est pas standardisé. De plus, la balise <video> ne supporte pas les DRM et le smooth streaming.

 
Pour <audio>, les codecs sont MP3, Vorbis (.ogg), AAC.
 
 
MP3
Vorbis
AAC
IE9
X
 
si extension .m4a ou .aac
Firefox 3.6
 
X
 
Chrome
X
X
si extension .m4a
 
Pour <video>, les codecs sont H264 (.mp4), WebM, Theora (.ogg).
 
 
H264
WebM
Theora
IE9
X
X*
 
Firefox 4
 
X
X
Chrome
 
X
X
Safari 5
X
   
Opera 11
 
X
X
* : téléchargement requis du codec
 

Les codecs ne sont pas pris en charge par tous les navigateurs. Par exemple, Firefox ne supporte pas H264 car il n'est pas ouvert (royalty free). Et Chrome prévoit de ne plus le supporter au profit de WebM. Bref, une guerre des codecs en perspective !

Pour le développeur, cela oblige à proposer à l'internaute un triple encodage de la vidéo et à faire du fallback.
Par exemple au sein de la balise <video>, on peut avoir une balise <object> pour charger un .xap (Silverlight), si le codec n'est pas pris en charge.

 
Exemple :
<video id="myVideo" controls autoplay>
  <source src="video.mp4" type="video/mp4; codecs='avc1.4201E,mp4a.40.2'" />
  <source src="video.ogg" type="video/ogg; codecs='theora,vorbis'" />
  <!-- insertion <object> silverlight -->
  <!-- insertion <object> flash -->
</video>

Un exemple plus poussé est donné sur le blog de Niall Kennedy, avec une détection JavaScript.

La balise <canvas> est une zone de dessin, manipulable avec des librairies JavaScript et les primitives, en initiant des contexts (méthode getContext()). Cette balise soulève un problème d'accessibilité car c'est une boite noire, et peut être très couteuse en terme de CPU. Il faut tirer parti de l'accélération matérielle que peut permettre le hardware de la machine (puce de la carte graphique). IE9 offre cette possibilité (voir le site Test Drive).

Les HTML5Forms (ou WebForms)

Attention, c'est toujours en working draft, et à ne pas confondre avec les webforms d'ASP.NET.
Les HTML5Forms ont été proposés par Opera, cela concerne des nouveaux types et attributs de la balise <input> afin de les rendre accessibles. Tous ces éléments ne sont pas tous pris en charge par les navigateurs. En fait, ces nouveautés existent déjà depuis quelques années (avec le web 2.0) en fallbacks avec des librairies AJAX, ou la librairie AjaxControlToolkit d'ASP.NET (gauge bar, calendar, etc.).

  • Attribut placeholder
    Il permet d'avoir un texte alternatif dans l'input lorsque celui-ci est vide et qu'il n'a pas le focus. Si le navigateur ne le prends en compte nativement, des fallbacks existent en jQuery, et plus anciennement avec le contrôle TextBoxWatermark de la librairie AjaxControlToolkit.
  • Attribut autofocus
    Permet d'avoir automatiquement le focus sur un input.
  • Et 13 nouveaux types (date, email, number, ..., etc.)

Quelques nouveautés du CSS3

On peut citer notamment, border-radius pour faire des coins arrondis, et box-shadow pour faire des ombres portées. background peut contenir un fichier *.svg. (un tag HTML ayant un box-shadow par dessus un background en SVG est supporté par IE9).
Des fallbacks existent si le navigateur ne les supporte pas, via des libraires JavaScript, ou en préfixant les instructions CSS en fonction des navigateurs (instructions propriétaires) :

 
<style type="text/css">
.rounded
{
    -moz-border-radius-topleft:3px; /* firefox */
    -moz-border-radius-topright:3px;
    -webkit-border-top-left-radius:3px; /* safari */
    -webkit-border-top-right-radius:3px;
    -khtml-border-top-left-radius:3px; /* konqueror*/
    -khtml-border-top-right-radius:3px;
    border-top-left-radius:3px; /* standard*/
    border-top-right-radius:3px;
}
</style>

Les Media Queries

Une fonctionnalité intéressante sont les Media Queries. Ils permettent d'adapter la résolution du client en fonction du poste client ou du device (smartphone, notebook, tablette), en chargeant des images plus petites. Ce qui évite l'implémentation d'un code JavaScript discriminant. La discrimination (ou device filtering) peut également se faire au chargement des fichiers CSS.

Exemple :
<link href="mobile.css" rel="Stylesheet" type="text/css" media="screen and (max-width:480px)" />
<link href="netbook.css" rel="Stylesheet" type="text/css" media="screen and (min-width:481px) and (max-width:1024px)" />
<link href="laptop.css" rel="Stylesheet" type="text/css" media="screen and (min-width:1025px)" />
On peut citer également les CSS3 animations, les CSS3 transitions mais sont pour l'instant en working draft et donc instables.

WOFF

Web Open Font Format est un wrapper des fonts au format True Type et Open Type. Il permet de télécharger des polices depuis le serveur (via CSS), de manière compressée (téléchargement plus rapide). Le WOFF est en cours de standardisation par le W3C et est soutenu par Microsoft, Mozilla, Opera. Il semble qu'il soit supporté par les dernières versions des navigateurs (sauf Safari actuellement).

SVG 1.1

Scalable Vector Graphics est un langage XML affichant des graphiques vectoriels (donc redimensionnables). Il est stylable par CSS, et est manipulable par JavaScript. SVG a l'avantage de l'accessibilité grâce aux propriétés aria ; mais a aussi l'inconvénient d'être très verbeux (c'est du XML) et peut être très lourd à charger si la page contient beaucoup de graphiques.
Typiquement, SVG est utilisé pour faire du charting. Un bon exemple est la librairie Highcharts JS. C'est une librairie JavaScript qui manipule des graphiques SVG et les rends interactifs.

WebGL

Est basé sur OpenGL, a pour but d'afficher de la 3D dans les pages web. Cette technologie est expérimentale et n'est pas pour l'instant un standard W3C.

Tests de conformité HTML5

Pour vérifier la conformité des pages web sur HTML5, il y a le validateur online du W3C. Le validateur vient d'intégrer dans son moteur le support du HTML5. Après avoir saisi l'URL d'un site, un rapport de test est généré affichant des erreurs et warnings :


 

En parallèle du test des pages web, il y a le test du navigateur pour vérifier si celui-ci intègre les fonctionnalités actuellement en standard, celles expérimentales (et celles propriétaires). Citons ACID3 (émanation du Web Standard Project) qui fait suite aux tests ACID2 et ACID1 ; et HTML5test. Mais ces tests font débat parmi les éditeurs et la communauté des développeurs, dans le contexte de compétition entre les navigateurs.

HTML5 sous Visual Studio

Des add-ons HTML5

La venue d'HTML5 a poussé la communauté ASP.NET à proposer des add-ons pour Visual Studio 2008/2010, mais pour l'instant c'est du ASP.NET MVC. D'ailleurs, MVC est "HTML compliant" et se prête bien à ça. Il n'est pas encore prévu d'avoir des WebControls ou HtmlControls encapsulant les nouvelles balises sur l'ASP.NET classique.
Ces add-ons sont visibles sur codeplex :

Il est possible également de créer un template pour Visual Studio, dans lequel les pages aspx générées auraient un squelette de code HTML5, mais cela mériterait un article sur ce sujet ;-)

Validation HTML5

Le SP1 de Visual Studio 2010 permet maintenant d'avoir un schéma de validation HTML5/XHTML5. Les nouvelles balises sont affichées avec l'intellisense. En revanche, la validation CSS3 n'est pas encore proposée.
Pour Visual Studio 2008, John Dyer a publié en 2009 un schéma de validation permettant d'avoir également l'intellisense.

Device filtering en ASP.NET classique

Une fonctionnalité bien pratique (et à mon avis peu conne) est de mettre en place des fichiers *.browser, dans le but de discriminer du code ou du contenu. Ce qui est affiché au end user est alors filtré en fonction de son navigateur client et/ou de son device (PC, smartphone, pocket PC). Au lieu de faire du test conditionnel en code behind via la propriété Request.Browser.Id, il est possible de le faire en déclaratif dans la page *.aspx.

Exemple de filtrage natif d'Internet Explorer et Firefox

Le device filtering peut s'effectuer sur des propriétés de contrôles HtmlControl ou WebControl, ou contrôles templatisés, ici en préfixant avec "ie" et "mozilla" :

 
<!-- Propriétés préfixées par ie ou mozilla -->
<asp:Label runat="server" ID="labelText"
    ie:Text="This is IE text"
    mozilla:Text="This is Firefox text"
    Text="This is general text"
/>
<br />
<asp:Button runat="server" ID="buttonText"
    ie:Text="IE Button"
    ie:OnClientClick="javascript:alert('Hello IE!');"
    mozilla:Text="FF Button"
    mozilla:OnClientClick="javascript:alert('Hello Firefox!');"
    Text="General Button"
    OnClientClick="javascript:alert('Hello everyone else!');"
/>
<br />
<asp:Menu runat="server" id="myMenu">
 
    <ie:Items>
       <asp:MenuItem Text="IE Item" />
    </ie:Items>
 
    <mozilla:Items>
       <asp:MenuItem Text="Firefox Item" />
    </mozilla:Items>
 
    <Items>
        <asp:MenuItem Text="Other Item" />
    </Items>
</asp:Menu>
 
Il peut s'effectuer également au niveau de certains attributs de la directive @page pour les pages *.aspx, ou la directive @control pour les usercontrols (voir une vue d'ensemble du device filtering en ASP.NET).
 
Cela peut être très utile lorsque on veut référencer une masterpage :
 
<%@ Page Language="C#"
    ie:MasterPageFile="~/MasterPageIE.master"
    mozilla:MasterPageFile="~/MasterPageFirefox.master"
    MasterPageFile="~/MasterPageGeneric.master"
%>

Comment cela fonctionne ?

Le filtrage en natif est basé sur des fichiers *.browser situés dans le répertoire C:\Windows\Microsoft.NET\Framework\<n° de version du fk>\Config\Browsers

 
 
Ce filtrage de base peut être surchargé par l'ajout d'un nouveau fichier *.browser dans une application ASP.NET.

Configurer le filtrage pour IE9, IE8, Firefox dans une application ASP.NET

A l'heure actuelle, le fichier ie.browser (situé dans C:\Windows\Microsoft.NET\Framework\<n° de version du fk>\Config\Browsers) ne contient pas (encore) de définition pour Internet Explorer 9. Il faut donc l'ajouter. Pour cela, il suffit d'ajouter à la racine de votre projet web un répertoire App_Browser (un répertoire réservé d'ASP.NET), lequel contiendra un nouveau fichier que vous nommerez ie9.browser.

 
 
Structure du fichier i9.browser :
 
<!--
You can find existing browser definitions at
<windir>\Microsoft.NET\Framework\<ver>\CONFIG\Browsers
-->
<browsers>
 
<browser id="IE9" parentID="IE6to9">
  <identification>
    <capability name="majorversion" match="9" />
  </identification>
  <capabilities>
    <capability name="jscriptversion" value="9.0" />
  </capabilities>
</browser>
 
</browsers>
 

La valeur de l'attribut parentID est une valeur existante dans le fichier ie.browser. La version du JScript pour IE9 a été reprise à partir des commentaires conditionnels (code côté client servant à discriminer la version d'Internet Explorer).

Pour illustrer le filtrage, nous allons mettre le code suivant dans la page Default.aspx :

 
<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="DeviceFiltering._Default" %>
 
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
  <style type="text/css">
    label{ margin:0 1em 0 0; }
  </style>
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
  <h2>Browser filtering in ASP.NET</h2>
 
  <!-- filtrage réalisé en code behind -->
  <div id="divIE9" runat="server">
    <asp:Label id="lblIE9" runat="server" AssociatedControlID="txtNameIE9">Votre nom (sous IE9)</asp:Label>
    <input id="txtNameIE9" runat="server" type="text" />
  </div>
  <div id="divIE8" runat="server">
    <asp:Label id="lblIE8" runat="server" AssociatedControlID="txtNameIE8">Votre nom (sous IE8)</asp:Label>
    <input id="txtNameIE8" runat="server" type="text" />
  </div>
  <div id="divFF" runat="server">
    <asp:Label id="lblFF" runat="server" AssociatedControlID="txtNameFF">Votre nom (sous Firefox)</asp:Label>
    <input id="txtNameFF" runat="server" type="text" autofocus="true" placeholder="Entrez votre nom" />
  </div>
  <div id="divBrowser" runat="server">
    <asp:Label id="Label1" runat="server" AssociatedControlID="txtName">Votre nom</asp:Label>
    <input id="txtName" runat="server" type="text" />
  </div>
 
  <!-- filtrage réalisé en déclaratif -->
  <p>
    <asp:Button ID="btnTest" runat="server"
         ie9:OnClientClick="javascript:alert('IE9 button!')"
         ie8:OnClientClick="javascript:alert('IE8 button!')"
         firefox35:OnClientClick="javascript:alert('Firefox button!')"
         ie9:Text="I'm a button for IE9"
         ie8:Text="I'm a button for IE8"
         firefox35:Text="I'm a button for Firefox" />
  </p>
 
</asp:Content>
 
Et le code suivant dans la page Default.aspx.cs :
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
 
namespace DeviceFiltering
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!this.IsPostBack)
            {
                divIE8.Visible = false;
                divIE9.Visible = false;
                divFF.Visible = false;
                divBrowser.Visible = false;
 
                switch (Request.Browser.Id)
                {
                    case "ie8":
                        divIE8.Visible = true;
                        break;
                    case "ie9":
                        divIE9.Visible = true;
                        break;
                    case "firefox35":
                        divFF.Visible = true;
                        break;
                    default:
                        divBrowser.Visible = true;
                        break;
 
                }
 
            }
        }
    }
}
 
Résultat sous IE9 :
 
 
Résultat sous IE9 en mode IE8 :
 
 
Résultat sous Firefox :
 

On peut donc remarquer que l'affichage du bouton se fait de manière déclarative, en préfixant un ID de browser sur un attribut et c'est fini ! :)

Conclusion

Le HTML5 est d'ores et déjà un progrès concernant la sémantique et l'accessibilité des pages web. Ses spécifications auront l'avantage de rendre natives des fonctionnalités telles que les webforms (actuellement rendues avec des librairies AJAX/JavaScript).
Mais attention au buzz marketing effectué autour, et à la dépendance des navigateurs. Car ceux-ci ne l'implémentent pas de la même manière, les performances peuvent être assez différentes d'un device à l'autre. Le HTML5 n'est absolument pas pour l'instant synonyme de développement unique !

Par ailleurs, d'autres briques du HTML5 n'ont pas été évoquées dans ce workshop. Citons le Web Storage (stockage de données dans le navigateur, cache d'application), le Web SQL Database (basé sur SQLite), les Web Workers (scripts JS tournant en tâche de fond), la géolocalisation (via une API JavaScript), les microdata (amélioration du référencement naturel par ajout de données dans les balises, lues uniquement par les robots).

A l'heure de l'expansion imminente du HTML5 sur les sites web et mobile, gageons que les futurs add-ons ou CTP d'ASP.NET apporteront leur lot de nouveauté !

Pour aller plus loin

 

Tags: , , ,

Développement | Evènement

Neos-SDI  Neos-SDI