Inclure JQuery 2.x pour les fureteurs récents et 1.x pour les récalcitrants

L’équipe derrière JQuery a pris la décision de laisser tomber le support pour Internet Explorer 6, 7 et 8 dans la branche 2.x.

Pour l’explication officielle, veuillez consulter jQuery Core: Version 1.9 and Beyond. En voici un extrait:

There’s just one thing interfering with our vision of the future, and that’s the ghost of browsers past. Internet Explorer 6, 7, and 8–collectively, oldIE–have been a thorn in the side of web developers for a decade.

L’API de la branche 2.x est compatible avec l’API de la branche JQuery 1.9+ qui supporte toujours les vielles versions.

Our goal is for 1.9 and 2.0 to be interchangeable as far as the API set they support. When 2.0 comes out, your decision on which version to choose should be as simple as this: If you need IE 6/7/8 support, choose 1.9; otherwise you can use either 1.9 or 2.0.

Cependant, pour y arriver, cette branche doit faire plusieurs pirouettes et tours de magie et cela complique le code et rend plus difficile son évolution. Ou encore mieux formulé (par l’équipe de JQuery):

If jQuery 1.9 and 2.0 are basically the same API, what makes 2.0 compelling?

Smaller size, better performance, and the lack of problems introduced by the need for oldIE support. We expect that we can improve error handling in the $.Deferred implementation in 2.0, for example, whereas we can’t do that as long as oldIE is supported.

En tant que développeur, on veut souvent profiter des dernières améliorations nous permettant d’écrire du code concis, efficace et avec le moins de défaut possible. On veut aussi minimiser le nombre de tests à effectuer. Tester un site pour IE 11, IE 10, IE 9 et Chrome est déjà beaucoup. Si en plus il faut tester avec IE 8, IE7 et IE6, cela rend les choses encore plus compliquées.

Même les grosses compagnies avec de gros comptes de banque et beaucoup d’employés préfèrent supporter les fureteurs récents. Par exemple, Google a abandonné le support pour IE9 quelque temps après la sortie de IE 11:

Google Drops Support for IE9

Alors si vous souhaitez travailler avec les dernières versions des fureteurs et la dernière version de JQuery lors du développement mais garder une porte ouverte pour supporter les vieux fureteurs si on client l’exige, voici un petite recette.

Recette pour inclure automatiquement la dernière version de JQuery dans un application ASP.Net MVC

  1. Ajoutez la dernière version de JQuery 2.x à votre projet ainsi que la dernière version de JQuery 1.ximage
  2. Dans la classe BundleConfig, ajoutez deux bundles:
    public static void RegisterBundles(BundleCollection bundles)
    {
    bundles.Add(new ScriptBundle(« ~/bundles/jquery1 »).Include(« ~/Scripts/jquery-1* »));
    bundles.Add(new ScriptBundle(« ~/bundles/jquery2 »).Include(« ~/Scripts/jquery-2* »));
    (…)
  3. Définissez une vue partielle nommée _JQueryInclude.cshtml et contenant les 5 lignes suivantes:<!– Conditionally include jQuery version based on IE version –>
    <!–[if lt IE 9]>
    @Scripts.Render(« ~/bundles/jquery1 ») <![endif]–>
    <!–[if gte IE 9]><!–>
    @Scripts.Render(« ~/bundles/jquery2 ») <!–<![endif]—>
  4. Dans votre layout page ou à l’endroit où vous désirez inclure JQuery, utilisez:@Html.Partial(« _JQueryInclude »)

Et voilà! Si vos utilisateurs utilisent IE 6, IE 7 ou IE 8, les pages HTML utiliseront la branche 1.x de JQuery. Autrement, la version moderne de la branche 2.x sera utilisée.

Caractères accentués, ASP.Net MVC Razor et boutons de dialogue JQuery UI

Développeurs MVC francophones: avez-vous déjà eu des problèmes avec des caractères accentués dans les boutons d’un dialogue JQuery UI?

Afin de développer l’application Web en anglais et français, les libellés des boutons sont stockés dans des fichiers de ressources (*.resx).

Tout fonctionnait avec des boutons comme Sauvegarder, Annuler, OK etc. Mais tout à coup, la technique habituelle échoue avec un bouton Générer …

image

Et s’il n’y avait pas de guillement pour la clé (Gén&/233;rer: function() { … ), c’est pire car cela fera planter votre script.

La solution est d’utiliser la méthode @Html.Raw et d’entourer le résultat avec des guillements:

$(« #dlgGenerator »).dialog({
  autoOpen: false,
  width: 800,
  height: 600,
  resizable: false,
  modal: true,
  open: function(event, ui) {
    // Initialization
  },
  buttons: {
    « @Html.Raw(Global.LblGenerate) »: function() {
      $(« #cmdGenerateAssignments »).click();
    },
    « @Html.Raw(Global.LblCancel) »: function() {
      $(this).dialog(« close »);
    }
  }
});

image

Il est peut-être sage de vous protéger tout de suite d’un changement de libellé éventuel! L’utilisation de Html.Raw vous protège des caractères accentués tandis que l’utilisation des guillemets empêchera les erreurs de script dûes à la présence d’un espace ou caractère illégal.

À la prochaine fois,

Recette améliorée: Intégrer une application ASP.Net MVC sous un site Web IIS hébergeant WSS 3.0 / SharePoint 2007

L’avantage de la recette précédente c’est qu’elle était simple et exigeait peu de modification au Web.Config des applications ASP.Net MVC. Mais elle avait l’inconvénient majeur de faire échouer plusieurs soutions (ex. solution qui ajoute des Safe Controls) car l’API de SharePoint ne semble pas supporter les clauses <location path= ». »> d’IIS. Il fallait donc enlever les location du web.config, procéder à l’installation puis les remettre.

Voici donc la nouvelle recette (l’étape 5 est enlevée et l’étape 7 a été ajoutée):

  1. Vous devez créer un « Application Pool” utilisant le “.NET Framework 4.0” et empruntant la même identité (le même compte de service) que l’ “Application Pool” de SharePoint.Puisque le site IIS a un SPN unique (ex. HTTP/nomgentil.domaine.com), celui-ci est déjà défini sur le compte de service en question. Ainsi, il suffira d’ajouter la déléguation vers SQL Server ou SSAS à ce compte selon ce que fait l’application ASP.Net.
  2. Vous devez copier le répertoire de votre application ASP.Net sous le répertoire contenant SharePoint. Ex. C:\Inetpub\wss\nomgentil.domain.com\ApplicationMVC
  3. Les permissions par défaut ne sont pas les même que pour les sites placés directement sous C:\Inetpub alors assurez-vous de donner les permissions Windows à Users ou autre au répertoire de votre application MVC.
  4. Il faut convertir le virtual directory en application dans IIS en prenant bien soin d’utiliser le pool d’application défini précédemment.
  5. Une application ASP.Net utilise un fichier Web.Config afin de configurer différents éléments propres à .Net. Ce qu’il faut savoir c’est qu’il y a un lien d’héritage entre les Web.Config des applications Web. Ainsi si l’application B est placée sous l’application A dans IIS, elle hérite du Web.Config.Le problème c’est qu’en étant sous SharePoint, on hérite de certains éléments incompatibles avec une application utilisant le “.NET Framework 4.0”.

    On n’ajoute plus de clause <location> autour des noeuds SharePoint.

  6. On hérite aussi des “Handler Mappings” du site SharePoint et il y en a beaucoup. Il faut au moins enlever (dans l’application ASP.Net MVC) celui qui intercepte * et qui porte le nom AboMapperCustom-<numéro> pointant vers ASP.Net 2.0 (aspnet_isapi.dll). Autrement les images, CSS et autres fichiers statiques ne fonctionneront pas.image

    Cela aura pour effet d’ajouter ceci au web.config de votre application:

    <handlers>
    < remove name= »AboMapperCustom-3515455823″ />
    < /handlers>

  7. Les permissions du site MVC sont maintenant héritées du site SharePoint ce qui provoque une erreur dans l’application MVC. Il faut donc ajouter les permissions nécessaires en ajoutant l’élément <trust> dans le web.config de l’application. Ex. :

    <system.web>
    <trust level="Full" originUrl="" />
    </system.web>
  8. IIS Reset
  9. Si vous avez une erreur qui dit que le fichier de configuration n’est pas accessible, donnez temporairement les droits en lecture au groupe local IIS_IUSRS sur ce fichier (l’erreur indique le chemin d’accès).Quand IIS n’arrive pas à déterminer l’authentification utilisée (ex. il y a un nœud dupliqué dans les web.config parent et enfant), il doit avoir accès en mode anonyme. Après l’erreur qui sera affichée sera détaillée (ex. le nœud qui ne peut être redéfini etc.)
  10. Si vous avez une erreur HTTP 500 ou une page blanche, même avec customErrors à OFF, vous pouvez utiliser la fonctionnalité des Failed Request Tracing (FREB). Voici comment l’activer pour un site / application.

    Request Diagnostics HTTP 500

Si vous ne souhaitez pas donner FullTrust à l’application ASP.Net, vous devez:

  1. Ajouter:

    using System.Security;
    [assembly: AllowPartiallyTrustedCallers()]

    dans le fichier AssemblyInfo.cs des Dlls utilisés par votre application afin qu’ils acceptent d’être appelés dans un contexte limité ne permissions.

  2. Définir un fichier de policy listant toutes les permissions nécessaires à votre application (vous pouvez partir d’un fichier utilisé par SharePoint).
  3. Inclure le fichier spécifique en lui donnant un nom et y référer:

    <system.web>
      <securityPolicy>
        <trustLevel name= »MVCTrustLevel » policyFile= »<fullpath> » />
      </securityPolicy>
      <trust level= »MVCTrustLevel » originUrl= » » />
    </system.web>

Bonne chance et à la prochaine …

Références
Troubleshooting HTTP 500.19 Errors in IIS 7
http://blogs.iis.net/webtopics/archive/2010/03/08/troubleshooting-http-500-19-errors-in-iis-7.aspx

Recette améliorée: Intégrer une application ASP.Net MVC 3 sous un site Web IIS hébergeant SharePoint Server 2010

L’avantage de la recette précédente c’est qu’elle était simple et exigeait peu de modification au Web.Config des applications ASP.Net MVC. Mais elle avait l’inconvénient majeur de faire échouer plusieurs soutions (ex. solution qui ajoute des Safe Controls) car l’API de SharePoint ne semble pas supporter les clauses <location path= ». »> d’IIS. Il fallait donc enlever les location du web.config, procéder à l’installation puis les remettre.

Voici donc la nouvelle recette (l’étape 5 est enlevée et l’étape 8 a été ajoutée):

  1. Vous devez créer un “Application Pool” utilisant le “.NET Framework 4.0” et empruntant la même identité (le même compte de service) que l’ “Application Pool” de SharePoint.Puisque le site IIS a un SPN unique (ex. HTTP/nomgentil.domaine.com), celui-ci est déjà défini sur le compte de service en question. Ainsi, il suffira d’ajouter la déléguation vers SQL Server ou SSAS à ce compte selon ce que fait l’application ASP.Net.
  2. Vous pouvez copier le répertoire de votre application ASP.Net sous le répertoire contenant SharePoint. Ex. C:\Inetpub\wss\nomgentil.domain.com\ApplicationMVCNote: Vous pouvez le mettre ailleurs mais cela fonctionne très bien à cet endroit.
  3. Les permissions par défaut ne sont pas les même que pour les sites placés directement sous C:\Inetpub alors assurez-vous de donner les permissions Windows à Users ou autre au répertoire de votre application MVC.
  4. Il faut convertir le virtual directory en application dans IIS en prenant bien soin d’utiliser le pool d’application défini précédemment.
  5. Une application ASP.Net utilise un fichier Web.Config afin de configurer différents éléments propres à .Net. Ce qu’il faut savoir c’est qu’il y a un lien d’héritage entre les Web.Config des applications Web. Ainsi si l’application B est placée sous l’application A dans IIS, elle hérite du Web.Config.Le problème c’est qu’en étant sous SharePoint, on hérite de certains éléments incompatibles avec une application utilisant le “.NET Framework 4.0”. Les étapes 6, 7 et 8 vont travailler dans ce sens.

    On n’ajoute plus de clause <location> autour des noeuds SharePoint.

  6. Il faut déplacer l’élément Xml <sectionGroup> nommé “system.web.extensions” du Web.Config de SharePoint vers le Web.Config qui se trouve à cet endroit: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG\Web.Config.

    On doit le mettre sous le noeud <configSections> directement sous <configuration>:

    <configuration>
    < configSections>
    <sectionGroup name= »system.web.extensions » …

    La raison est que le site ASP.Net MVC 3 .NET 4 hérite du Web.Config de SharePoint et ce sectionGroup cause une erreur. On ne peut pas utiliser l’élément <location> à cet endroit. En déplaçant la déclaration directement dans le Web.Config du .NET Framework 2.0, SharePoint en héritera mais pas notre application ASP.Net.

    Vous pouvez obtenir plus d’information ici. Un extrait:

    Move the configSections definition in the Web.config file of the parent application (the application that runs ASP.NET 2.0 or ASP.NET 3.5) into the root Web.config file for the.NET Framework 2.0. The IIS 7 and IIS 7.5 native configuration system scans the configSections element when it merges the hierarchy of configuration files. Moving the configSections definition from the parent Web application’s Web.config file to the root Web.config file effectively hides the element from the configuration merge process that occurs for the child ASP.NET 4 application.

  7. On hérite aussi des Modules du site SharePoint et ceux-ci causent une erreur (en particulier SharePoint14Module). La solution est d’utiliser ce noeud <modules> dans votre application ASP.Net:

    <modules runAllManagedModulesForAllRequests= »true »>
    < remove name= »SPRequestModule » />
    < remove name= »PublishingHttpModule » />
    < remove name= »RSRedirectModule » />
    < remove name= »StateServiceModule » />
    < remove name= »SharePoint14Module » />
    < add name= »Session » type= »System.Web.SessionState.SessionStateModule » />
    < /modules>

    Notez qu’en plus d’enlever les modules spécifiques à SharePoint, on réactive la gestion des Session. Si vous ne le faites pas, vous ne pourrez pas utiliser l’objet Session.

    En fait, comme on ne peut pas utiliser la clause <location> pour <system.webServer>, il faut défaire ce qui est fait par SharePoint. Il se peut que votre implantation nécessite d’activer / désactiver certains modules / “Http Handlers”. Voici un extrait de ce que SharePoint active / désactive:

    <modules runAllManagedModulesForAllRequests= »true »>
    < remove name= »AnonymousIdentification » />
    < remove name= »FileAuthorization » />
    < remove name= »Profile » />
    < remove name= »WebDAVModule » />
    < remove name= »Session » />
    < add name= »SPRequestModule » … />
    < add name= »ScriptModule »  … />
    < add name= »SharePoint14Module » … />
    < add name= »StateServiceModule » … />
    < add name= »RSRedirectModule » … />
    < add name= »PublishingHttpModule » … />
    < /modules>
    < handlers>
    < remove name= »OPTIONSVerbHandler » />
    < remove name= »WebServiceHandlerFactory-Integrated » />
    < remove name= »svc-Integrated » />
    < remove name= »WebDAV » />
    < add name= »svc-Integrated » … />
    < add name= »OwssvrHandler » … />
    < add name= »ScriptHandlerFactory » … />
    < add name= »ScriptHandlerFactoryAppServices » … />
    < add name= »ScriptResource » …  />
    < add name= »JSONHandlerFactory » … />
    < add name= »ReportViewerWebPart » … />
    < add name= »ReportViewerWebControl » … />
    < /handlers>

  8. Les permissions du site MVC sont maintenant héritées du site SharePoint ce qui provoque une erreur dans l’application MVC. Il faut donc ajouter les permissions nécessaires en ajoutant l’élément <trust> dans le web.config de l’application. Ex. :

    <system.web>
    <trust level="Full" originUrl="" />
    </system.web>
  9. IIS Reset
  10. Si vous avez une erreur qui dit que le fichier de configuration n’est pas accessible, donnez temporairement les droits en lecture au groupe local IIS_IUSRS sur ce fichier (l’erreur indique le chemin d’accès).

    Quand IIS n’arrive pas à déterminer l’authentification utilisée (ex. il y a un nœud dupliqué dans les web.config parent et enfant), il doit avoir accès en mode anonyme. Après l’erreur qui sera affichée sera détaillée (ex. le nœud qui ne peut être redéfini etc.)

  11. Si vous avez une erreur HTTP 500 ou une page blanche, même avec customErrors à OFF, vous pouvez utiliser la fonctionnalité des Failed Request Tracing (FREB). Voici comment l’activer pour un site / application.

    C’est ainsi que j’ai su qu’il me fallait désactiver le module SharePoint14Module:

    Request Diagnostics HTTP 500

Bref, oui c’est possible de mettre une application ASP.Net MVC 3 sous SharePoint 2010 mais il faut quand même effectuer un certain nombre de manipulations …

Si vous ne souhaitez pas donner FullTrust à l’application ASP.Net, vous devez:

  1. Ajouter:

    using System.Security;
    [assembly: AllowPartiallyTrustedCallers()]

    dans le fichier AssemblyInfo.cs des Dlls utilisés par votre application afin qu’ils acceptent d’être appelés dans un contexte limité ne permissions.

  2. Définir un fichier de policy listant toutes les permissions nécessaires à votre application (vous pouvez partir d’un fichier utilisé par SharePoint).
  3. Inclure le fichier spécifique en lui donnant un nom et y référer:

    <system.web>
      <securityPolicy>
        <trustLevel name= »MVCTrustLevel » policyFile= »<fullpath> » />
      </securityPolicy>
      <trust level= »MVCTrustLevel » originUrl= » » />
    </system.web>

Bonne chance et à la prochaine …

Comment impersonifier temporairement l’identité du AppPool en ASP.Net

Il est fréquent d’impersonifier l’identité du l’utilisateur dans une application ASP.Net MVC. L’application est personnalisée ou sécuritée par utilisateur ce qui nous empêche d’impersonifier un compte de service précis.

Normalement, avec une connaissance de Kerberos, il est facile de faire en sorte que l’identité de l’utilisateur voyage jusqu’aux différents serveurs de données (SQL Server, Analysis Services etc.).

Mais dans certains cas, la délégation Kerberos n’est pas envisageable. C’est en autre le cas pour l’API qui se trouve dans System.DirectoryServices. Cet API permet d’interroger Active Directory afin d’obtenir les groupes dont un utilisateur fait partie ou d’aller chercher des propriétés etc.

Même si cet API est en .NET, ça semble utiliser des fonctonnalités COM et il semblerait que la délégation Kerberos n’est pas supportée dans ce scénario. En effet, lors d’un Double Hop, l’erreur suivante est obtenue lors de l’utilisation des classes de System.DirectoryServices:

[COMException (0x80072020): An operations error occurred. ]

Le KB329986propose des solutions mais aucune ne nous semblait acceptable pour notre besoin (ex. utiliser l’authentification basique).

Heureusement, nos applications ASP.Net MVC s’exécutent sous un AppPool ayant une identité d’un compte de domaine (le même que pour SharePoint lorsque l’application MVC est hébergée sous SharePoint). Il est possible d’exécuter un bloc de code sous l’identité du compte de service du AppPool en utilisant:

using (HostingEnvironment.Impersonate()) {

// Ce code s’exécute avec l’identité
// assignée au pool d’application (AppPool)

DirectorySearcher searcher …
}

Il faut ajouter une référence àSystem.Web.dll et faire un usingSystem.Web.Hosting.

Cette technique a l’avantage de contrôler les lignes de code devant s’exécuter sous le compte du AppPool. Tout le reste peut continuer de s’exécuter sous l’identité de l’utilisateur du fureteur.

Dans le cas précis de l’accès à Active Directory, cette technique offre un autre avantage. Plutôt que d’avoir à donner accès en lecture à Active Directory à tous vos utilisateurs, vous pouvez accorder ce droit uniquement au compte de domaine assigné au AppPool.

Références

How to use the System.DirectoryServices namespace in ASP.NET

Quelles sont les compétences nécessaires pour être un bon développeur ASP.Net MVC?

Vous avez un projet pour une application Web incluant de la saisie de données? Vous cherchez des ressources internes ou externes pour réaliser la solution? Quelles sont les aptitudes techniques qui doivent être maîtrisées et du moins à apprendre par les ressources identifiées?

Plutôt que de créer une couche d’abstraction par dessus le DHTML, Microsoft a plutôt créé un environnement qui facilite sa génération. Ainsi, comme les technologies Web évoluent vite, les projets ASP.Net MVC peuvent en profiter immédiatement plutôt que d’attendre que la couche d’abstraction soit mise à jour.

Ainsi, il faut d’abord maîtriser les éléments suivants avant de se lancer dans le développement ASP.Net MVC:

Technologie Raisonnemment
HTML Le contenu des pages, une partie de la structure ainsi que les formulaires sont tous définis en HTML.
CSS Idéalement le formatage est défini dans des fichiers de styles externes afin de faciliter la maintenance et les changements importants de look.
JavaScript Peu de sites Web en 2012 n’ont pas besoin du JavaScript pour effectuer des validations, de la logique applicative ou de la transformation d’éléments HTML simples en contrôles interactifs.Ce code s’exécute sur le poste client (fureteur).
C# ou VB.Net Un projet ASP.Net est bâti en utilisant un language du .Net Framework. Il s’agit du code qui s’exécute sur le serveur et non sur le poste client.
SQL et base de données La plupart des projets ASP.Net se connectent sur des bases de données afin d’obtenir ou modifier de l’information. Un développeur doit connaître ces éléments.

Ensuite, il faudra prendre le temps d’apprendre les éléments suivants:

Technologie Raisonnemment
MVC Il s’agit d’une manière de structurer le projet, la logique applicative et le traitement des Urls.En bref:- Les modèles devraient contenir les classes qui représentent les données et la logique d’affaires de l’application à créer.

– Les vues savent comment afficher un modèle donné. Il peut s’agir de générer du HTML, du Xml, du JSON + JavaScript (ex. Sencha Charts). La vue connaît le modèle et sait comment référer aux controlleurs via des hyperliens.

– Les controlleurs sont appelés à partir des règles de “Routing”. La plomberie ASP.Net MVC va transformer un hyperlien en un appel de méthode dans une classe de controlleur avec une correspondance automatique des paramètres (et même leur conversion). Le rôle des controlleurs est d’obtenir tous les paramètres de la requête, d’aller chercher/ créer le modèle et de retourner une vue en lui passant le modèle.

Razor Avant “Razor”, on utilisait les “Web Form” et c’était difficile de distinguer le contenu HTML du code. Ce language permet de mixer du HTML et du code de manière optimale avec des @if, @switch, @foreach etc. On aime tout de suite ce langage en l’utilisant …
LINQ To SQL Microsoft a fait un excellent travail en créant LINQ qui évite d’avoir à concaténer des chaînes de caractères pour créer des requêtes SQL. Avec les “Nullable Types” (ex. int?, double?), le C# devient un langage de premier niveau pour du développement utilisant des bases de données.LINQ To SQL permet de créer une couche d’accès aux données simplement en important la définition des tables à partir de la base de données. Souvent le développeur ajoutera des méthodes à la classe DataContext (vive les classes partielles) qui seront des facilitants pour l’obtention, l’ajout et surtout la destruction des différentes entités. Mais on est loin de l’époque où il fallait écrire les couches de données à partir de zéro …

Cela fait déjà beaucoup de chose à apprendre. Mais ce n’est pas tout. En 2012, on ne peut plus afficher de simples contrôles Html (ListBox, TextBox etc.)

Les utilisateurs s’attendent à avoir des contrôles évolués tels que:

ListBox à sélection multiple:
image
http://www.quasipartikel.at/multiselect/

Calendrier avec l’heure:
image
http://trentrichardson.com/examples/timepicker/

Et c’est pourquoi je me dois d’ajouter JQuery à la liste des compétences nécessaires. Cette librairie permet de laisser le HTML le plus près possible de “ce qu’il représente” (ex. un ListBox à sélection multiple) et d’utiliser du JavaScript pour venir le transformer directement en un contrôle évolué. Souvent une seule ligne peut suffire:

$(‘#example1’).datetimepicker();

Bonne chance dans votre apprentissage ou votre recherche de candidats!