jeudi 6 mars 2014

Windows Authentication et IIS

Voici un problème qui m'aura bien fait souffrir : je souhaitais mettre en place pour un site sous DNN, un SSO basé sur l'authentification windows. Il s'agissait donc de définir une page ASPX sur laquelle la connexion anonyme était désactivée et l'authentification Windows activée. Sur le papier, cela me permet lorsque je me connecte sur cette page de récupérer automatiquement le compte Windows de l'utilisateur et ainsi de l'identifier automatiquement (SSO donc) pour peu qu'il utilise IE. Pour FireFox et Chrome, quelques manipulations de paramétrage sont a effectuer au préalable pour arriver à ce résultat.

Sur mon poste (un Windows 7 x64), je me suis retrouvé face à un problème terriblement déroutant (cela m'a occupé 1 jour 1/2 avant de trouver la solution). Lorsque je me connectais sur cette page où l'authentification windows était activée, mon navigateur me demandait de m'identifier, chose que je faisais une première fois, puis la fenêtre de login revenait et impossible de s'en défaire... Ma saisie semblait systématiquement incorrecte.

J'ai déployé ma solution sur le poste de mon collègue et avec le même paramétrage je ne rencontrais aucun soucis, j'étais automatiquement identifié sans avoir à saisir la moindre information dans une fenêtre de login. Il y avait bien entendu une différence quelque part... suffisait de la trouver.

Le problème venait du fait que sur mon site web j'avais défini un nom d'hôte, et sur le poste de mon collègue on travaillait en localhost avec un port. En supprimant le nom d'hôte et en travaillant en localhost mon problème était résolu... mais cette solution ne me satisfaisait pas, je tenais à travailler avec un nom d'hôte et pas un port différent.

En creusant pas mal je suis tombé sur cette KB : http://support.microsoft.com/kb/896861. J'ai utilisé la méthode 2 et là plus de soucis : j'ai gardé mon nom d'hôte et j'ai mon SSO qui fonctionne.

mardi 16 juillet 2013

Telerik, jQuery et ses "selector"

Voici un petit script javascript permettant d'accéder à un contrôle parent d'un "RadButton" lors d'un clique sur ce dernier.

Syntaxe du RadButton :
<telerik:RadButton ID="btnTest" runat="server" OnClientClicked="TestFonctionJS"></telerik:RadButton>

Syntaxe de la fonction JS :
 <script type="text/javascript">
function RelatedItemSelection(sender, args) {
    var parentControl= $(sender.get_element()).closest('.ClassParent');
}
</script>

La petite astuce consiste à utiliser la syntaxe $(sender.get_element()) pour récupérer l'élément "RadButton".

vendredi 7 juin 2013

Méthodes d'extensions

Vous trouverez des tonnes d'exemples concernant les méthodes d'extensions. Je ne vais donc pas m'étaler longuement sur le sujet, voici un lien où le sujet est très bien couvert : Méthodes d'extension.

Juste pour mémoire, voici un petit exemple de ce que donne une méthode d'extension. Dans cet exemple nous allons "étendre" une énumération :
    public enum TestEnum
    {
        Longueur9,
        Longueur10
    }

Nous souhaitons ajouter à l'énumération "TestEnum" une fonction permettant de calculer la longueur de la valeur de l'énumération. Ainsi l'appel :
TestEnum.Longueur9.Count()

Donnerait la valeur : 9. Sans intérêt mais c'est un cas d'école...

Pour cela, il suffit de créer la classe suivante :

    public static class MyExtensions
    {
        public static int Count(this TestEnum param)
        {
            return param.ToString().Length;
        }
    }

A partir de ce moment, l'intellissense de VS vous proposera la fonction "Count" dès lors que vous êtes sur une valeur de l'énumération "TestEnum".

lundi 11 février 2013

Problème d'utilisation du RadProgressManager dans DNN

Le controle RadProgressManager de Telerik permet de visualiser l'avancement d'une tâche sous forme de progress bar. Il est notemment utilisé par le RadUpload mais peut aussi être utilisé seul.

Je ne vais pas m'étaler ici sur les détails de son utilisation par contre j'ai rencontré un gros soucis lors de son utilisation sous DNN : une déconnexion systématique de l'utilisateur après un postback suite à un click sur un bouton.

Il m'a fallu plus de trois heures pour isoler ce problème et trouver une solution. J'utilisais ce contrôle pour représenter l'avancée d'un traitement d'export de données dans un module DNN. Mon traitement d'export se déroulait parfaitement bien, une fois terminé je revenais sur ma page d'appel et dès que je voulais naviguer au sein de DNN, je me retrouvais sur la page de connexion pour m'identifier, en clair j'étais déconnecté. En supprimant le module contrôle RadProgressManager le problème disparaissait : le coupable était trouvé.

Pour faire court voici la solution qui a fonctionné pour moi : initialiser la propriété "AjaxUrl" du contrôle. Voici ce que cela donne :

ProgressManager.AjaxUrl = Page.ResolveUrl("~/Telerik.RadUploadProgressHandler.ashx") + "?TabId=" + TabId;

J'ai placé ce code dans le "Load" de mon contrôle.

Je suis tombé sur la solution en me baladant sur le forum de Telerik, cette solution était donné par un utilisateur et pas par le support. Apparemment le problème pourrait venir de l'Url rewriter de DNN.


Bon courage.

samedi 2 février 2013

Développement d'un module DNN en mode WAP.. c'est lent mais... comment changer cela ?

Si vous êtes un habitué du développement de modules sous DNN, vous avez certainement été confronté au choix cornélien du type de projet Web que vous alliez utiliser : WSP ou WAP ?

WSP : compilation rapide, une modification dans le code de votre module est prise en compte en Live. Par contre côté déploiement et gestion des version de vos sources : bonjour galère !

WAP : votre module est un projet à part entière, donc une DLL pour un module, le déploiement est donc largement simplifié et idem pour la gestion des versions de vos sources. Par contre, une modification du module même mineure nécessite un rechargement de DNN et là...il ne vaut mieux pas être pressé.

Cela fait des années que je passe d'un type de projet à l'autre sans jamais être satisfait et bien là, ce soir, je viens de trouver un "truc" quasi-miraculeux. Après une ultime recherche dans Google voici le petit truc qui fait une sacrée différence : on part sur la solution WAP et dans le fichier config de DNN vous n'avez qu'à rajouter l'attribut "optimizeCompilations" à la balise compilation:
<compilation debug="true" optimizeCompilations="true" strict="false">
Et voici l'article qui fait référence à ce "truc" : http://www.dotnetnuke.com/Resources/Blogs/EntryId/2579/A-small-web-config-setting-that-can-save-you-development-time.aspx

DNN7 - VS2012 : c'est parti...

Me voilà parti dans le développement de modules DNN7 sous VS2012.... Enfin je ne suis pas parti bien loin.

Après avoir mis en place mon environnement de développement en suivant les très bons Wiki suivants :
  •  http://www.dotnetnuke.com/Resources/Wiki/Page/development-environment.aspx
  •  http://www.dotnetnuke.com/Resources/Wiki/Page/Visual-Studio-2012-Templates/NoRedirect/1.aspx#Version_History
j'ai compilé mon premier module (généré à partir du template DotNetNuke). La compilation se passe parfaitement bien, je m'empresse donc de lancer mon instance de DNN et là... erreur.

J'ai une superbe page avec le logo de la société fictive du template par défaut et le message "DotNetNuke Error". Je relance mon instance de DNN cette fois en passant par VS2012, là j'ai un peu plus d'info car l'erreur 'unexpected error' se lève sur la ligne suivante :
ctlSkin = IsPopUp ? UI.Skins.Skin.GetPopUpSkin(this) : UI.Skins.Skin.GetSkin(this);
Après pas mal de recherche sur le net, je m’aperçois que cette erreur est courante mais, bien sur, pas toujours pour la même raison. Alors que j'étais en train de télécharger les sources de DNN, je tombe sur une personne qui a rencontré le problème juste après avoir fait une compilation d'un module généré à partir du template (tiens donc!), et là... voici la solution...

Apparemment le template génère des choses dans IIS : un alias sur le répertoire "DesktopModules" et une application sur le répertoire de votre module, les deux sont à supprimer et là "oh miracle" tout refonctionne.

Bon courage...

mercredi 5 décembre 2012

Exécution des batchs défini dans le Scheduler

Après avoir mis en place un batch dans le scheduler je m'étonnais de son fonctionnement : j'avais l'impression que celui-ci ne tenait pas vraiment compte de la périodicité que j'avais pu définir.

Une rapide recherche sur Google me démontrait que mes soupçons étaient fondés. En effet, un paramétrage au niveau du host permet de déterminer le mode d'exécution du scheduler. Trois modes sont disponibles :
  • Disabled,
  • Request Method : c'est à chaque appel au site que les périodicités sont évaluées (c'était le mode dans lequel je me trouvais et qui semblait fonctionner "bizarrement"),
  • Timer Method : le scheduler est exécuté dans un autre thread que celui du site, un timer est exécuté pour gérer la périodicité des batchs.
Ce paramétrage s'effectue en accédant au menu "Host \ Host Settings", onglet "Other settings", champ "Scheduler Mode".

Une fois ce paramétrage mis en place, le fonctionnement de mon batch semblait plus correspondre à ce que j'en attendais.