vendredi 3 avril 2015

Comment récupérer les rôles définis dans DNN

Pour récupérer les rôles de DNN, je pensais devoir utiliser le controller "RoleController", et bien non...

Voici un extrait de code, vous permettant de récupérer l'ensemble des rôles définis dans une instance de portail :
ArrayList roles = RoleProvider.Instance().GetRoles(portalId);

Un ArrayList n'est pas forcément des plus simple à utiliser, voici la même chose mais en initialisant un objet List<RoleInfo> :

List<RoleInfo> roles = RoleProvider.Instance().GetRoles(portalId).Cast<RoleInfo>().ToList();

mardi 31 mars 2015

Utiliser Telerik OpenAccess sans avoir à l'installer

Voici une méthode permettant d'utiliser Telerik OpenAccess sans avoir à l'installer. Cette méthode peut aussi être utilisée pour détacher votre projet de la version de Telerik installé sur votre poste.

L'intérêt ? Vous avez une dizaine de projets sur votre poste utilisant Telerik OpenAccess mais bien sur, tous ne vont pas évoluer de la même façon. A un moment donné vous mettrez forcément à jour votre version d'OpenAccess, mais que se passera-t-il pour vos projets ?

Si vos projets sont détachés de la version installée sur votre poste vous n'aurez pas de soucis, sinon attention aux effets de bords, et généralement on les découvre quelques mois après la mise à jour d'OpenAccess lorsque vous retournez sur un projet.

L'idée est donc d'avoir dans votre solution les fichiers OpenAccess vous permettant de compiler sans soucis de version installée sur votre poste. Vous trouverez toutes les infos dans cet article :

http://docs.telerik.com/data-access/developers-guide/integrating-data-access-in-your-solution/external-tools-howto-integrate-enhancer-msbuild

jeudi 12 février 2015

Erreur 405, lors d'un appel Ajax avec le verb DELETE


Lors d'un appel Ajax à une web API avec le verbe DELETE, j'obtenais en retour une erreur 405 (Method Not Allowed).

Voici un extrait du code que j'utilise :

$.ajax({
    url: "/.../API/.../DeleteForm?" + $.param({ id: form.id }),
    type: "DELETE",
    contentType: 'application/json',
    success: function (result) {
    ...
    },
    error: function (result) {
    ...
    }
})
Après quelques recherches je me suis aperçu que ce problème pouvait provenir de la présence de WebDAV qui semble interférer mon appel.

Une solution consiste à désinstaller WebDAV...rien que ça. Sinon une autre solution consiste à désactiver les modules WebDAV au niveau de votre site. Pour cela vous pouvez utiliser le code suivant dans votre fichier web.config :
<system.webServer>
  <modules>
    <remove name="WebDAVModule" />
  </modules>
  <handlers>
    <remove name="WebDAV" />
  </handlers>
</system.webServer>
Et avec cela plus de soucis.

mardi 10 février 2015

Comment utiliser RequireJS sur un site DNN

Voici un sujet pour lequel je n'ai jamais réussi à trouver d'informations auprès de mon ami "Google". Après pas mal de tâtonnement, j'ai, il me semble, trouvé une solution à peu près convenable.

La notion de "component" sous Knockout

J'ai décidé de me pencher sur ce sujet lorsque j'ai découvert la notion de "component" sous Knockout. Cette notion permet de faire des développements Javascript modulaires, ce qui signifie plus de souplesse, plus facile à maintenir... voici un lien vous présentant un peu le sujet : http://knockoutjs.com/documentation/component-overview.html.
Quel est le lien avec RequireJS ? La modularité. Comme je le disais plus haut, vous développez de façon modulaire, chaque module peut être lié à d'autres modules. Comment gérer ces liens et comment faire en sorte que lorsque vous décidez d'utiliser un "component" tous les "components" liés soient bien récupérer par le client ?
C'est là que la puissance de RequireJS prend toute son ampleur.

Le chainage des "components" avec RequireJS

Sur chaque "component" vous allez définir les autres "components" devant être récupérés pour pouvoir fonctionner. Chacun des "components" récupérés ayant eux-mêmes d'autres "components" de référencés. Il se crée ainsi un chainage entre "components". Vous n'avez plus besoin de vous inquiéter si telle ou telle librarie JS a bien été intégrée dans le "header", tout ce fait automatiquement et seuls les éléments nécessaires sont récupérés.

Chargement de RequireJS dans DNN

RequireJS est donc essentiel pour un développement JS modulaire. Maintenant il ne nous reste plus qu'à le charger sur notre site DNN mais voilà...ce n'est pas si simple que cela : RequireJS ne doit être chargé qu'une seule fois.
Sous DNN nous avons l'habitude travailler avec des modules qui sont indépendants les uns des autres, nous aurions donc pu imaginer utiliser RequireJS dans chaque module...malheureusement cela n'est pas possible.
RequireJS n'est pas une librairie JS comme les autres, en effet, lors de la mise en place de la balise SCRIPT permettant de charger RequireJS il faut faire référence à un fichier de configuration qui sera exécuté une fois RequireJS chargé sur le client. On ne peut définir qu'un seul fichier de configuration par page. Donc imaginer monter une instance de RequireJS par module n'est pas possible (où en tout cas je n'ai pas trouvé comment le faire).

Un SKINOBJECT pour charger RequireJS

Je suis donc parti sur la création d'un SKINOBJECT pour charger sur mes pages ma librairie RequireJS. Ce SKINOBJECT est ensuite déposé sur les SKIN où je souhaite utiliser cette librairie.

Voici donc le code C# de mon SKINOBJECT :

    public partial class View : DotNetNuke.UI.Skins.SkinObjectBase
    {
        protected override void OnInit(EventArgs e)
        {
            LiteralControl javascriptRef = new LiteralControl("<script type='text/javascript' data-main='/PathToConfigFile/default.js' src='/PathToLibrary/require.js'></script>");

            Page.Header.Controls.Add(javascriptRef);
        }
    }
Ici, j'insère une balise script dans le "Header" de ma page. Cette balise script pointe vers deux fichiers : "default.js" et "require.js".
Le premier ("default.js"), correspond au fichier de configuration exécuté par RequireJS dès son chargement. Vous trouverez plus loin un descriptif du contenu de ce fichier.
Le second ("require.js") est ni plus ni moins que la librairie RequireJS.

Voici le contenu du fichier "default.js" :
require.config({
    baseUrl: '/DesktopModules',
    paths: {
        "knockout": 'PathToKnockout/knockout',
    },
});


require(["knockout"], function (ko) {
    $(document).ready(function () {
        $.event.trigger("knockoutReady")

        setTimeout(function () {
            ko.applyBindings();
        }, 10);
    });
});
Ce fichier de configuration permet de définir l'URL de base de l'ensemble des chemins utilisés dans RequireJS par la suite ainsi que le chemin d'accès à la librairie "Knockout" (ce chemin étant relatif à la baseUrl s'il ne commence pas par "/").

La seconde partie de ce fichier, permet de mettre en place le Binding de Knockout. Pour cela j'utilise 2 astuces :
  • je lève un événement "knockoutReady" que j'utiliserais dans mes modules utilisant des "components" Knockout pour charger ces derniers.
  • je fais un "applyBindings" en asynchrone pour "binder" les viewModels de mes futurs modules.
Avec cela je suis fin prêt pour créer mes modules avec des "components" dans tous les sens.

vendredi 12 décembre 2014

Telerik : No primary key fields found for class

Voici donc un message d'erreur obtenu lors de l'exécution d'une requête Lync sur une de mes tables gérées à travers DataAccess ORM de Telerik (anciennement OpenAccess).

A en croire ce message je n'ai pas de clef définie sur cette table. Et pourtant... dans le model, j'ai bien une clef de défini. Pour remédier à ce soucis, j'ai dû supprimer la clef, puis enregistrer mes modifications, j'ai eu droits à quelques messages d'erreur correspondant aux FOREIGN KEY qui ne pouvait plus se résoudre. J'ai remis en place ma clef, resauvegarder, puis exécuter l'application et... problème résolu.

Pour supprimer/créer la clef j'ai juste passé de false à true le propriété Identity de mon champ clef.

ClickOnce

Pas grande chose à voir avec DotNetNuke (sujet principal de ce blog). Mais voici une problématique face à laquelle je me suis retrouvé et qui m'a donné quelques sueurs froides : le renouvellement d'un certificat d'une application ClickOnce.

Lors de la création d'une application ClickOnce, les manifestes sont automatiquement signés. En effet, la case à cocher "Signer les manifestes ClickOnce" se trouvant dans l'onglet "Signature" des propriétés du projet est pré-coché. Cela ne pose aucune problème jusqu'à la date de péremption du certificat c'est à dire 1 an après la première publication.

Après que se passe-t-il ? Plusieurs possibilités :
  • vous créez un nouveau certificat, cela induit que vous acceptiez que vos utilisateurs doivent supprimer votre ancienne version pour installer la nouvelle... pas vraiment pratique,
  • vous avez sous le coude le certificat (fichier .pfx) qui a été créé initialement, et là vous n'avez plus qu'à le prolonger et redéployer et c'est reparti pour un tour,
  • vous n'avez pas le certificat, et là vous pouvez soit pleurer, soit accepter "contraint et forcer" la première solution.
Nous allons nous pencher sur la meilleure des solutions : renouvellement du certificat.

Pour info le certificat généré initialement, se trouve normalement à la racine de votre projet.

Voici l'article que vous permettra de procéder au renouvellement du certificat : http://robindotnet.wordpress.com/2010/01/26/how-to-extend-an-existing-certificate-even-if-it-has-expired/

Pour résumé, il vous faut dans un premier temps récupérer un exécutable permettant de renouveler le certificat, celui-ci a pour nom "renewcert.exe".

Ensuite, exécuter la ligne de commande suivante :
renewcert <FichierPfxOrigine> <FichierPfxDestination>.

Vous obtiendrez alors un fichier certificat pfx dont la date aura été étendue de 5 ans. Il ne vous reste plus qu' remplacer votre ancien certificat en passant par les propriétés du projet onglet "Signature" puis le bouton"A partir d'un fichier...".

Problème réglé.

dimanche 12 octobre 2014

DNN + Bootstrap + DDRMenu : Comment garder ouvert un sous-menu

Voici une petite astuce à utiliser dans un cas très précis. Je travaille actuellement sur un skin DNN, basé sur Bootstrap. Arrive le moment tant redouté de l'intégration du menu DNN (DDRMenu) dans le skin et je rencontre là un problème pour la gestion du menu "Rechercher".

En effet, dans DNN lors de la sélection du menu rechercher, un panel s'ouvre permettant de saisir le texte rechercher. Pour intégrer ce genre de fonctionnalité avec Bootstrap, l'utilisation d'un menu dropdown s'impose. Malheureusement lors de la sélection d'un sous-item la dropdown est automatiquement fermé. Mais dans mon cas cela pose soucis, puisque dès que ma zone de texte de mon contrôle de recherche prend le focus, la dropdown se referme.

A tout problème une solution... Voici tout d'abord la définition de mon menu rechercher "à la Bootstrap" :

<ul class="nav navbar-nav searchMenu">
     <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Search<b class="caret"></b></a>
               <ul class="dropdown-menu">
                    <li>
                         <div class="searchBox">
                              <dnn:Search id="dnnSearch1" runat="server" showsite="false" showweb="false" cssclass="btn btn-success btn-xs" />
                         </div>
                    </li>
               </ul>
          </li>
     </ul>
Cette définition permet d'avoir une dropdown "Search" qui a pour contenu, lorsqu'on la déplie, le contrôle de recherche DNN constitué d'une zone de texte et d'un bouton "Rechercher". Si l'utilisateur clique dans la zone de texte, la dropdown est automatiquement fermé.

Pour éviter cela, il s'agit dans un premier temps de supprimer l'attribut "data-toggle='dropdown'" définie sur l'élément "A" de la dropdown. En supprimant cet attribut, la dropdown ne s'ouvre plus.

L'étape suivante consiste à remettre en place le fonctionnement de la dropdown avec du javascript tout en excluant les cas où l'on ne souhaite pas que la dropdown se ferme. Voici le code JS à mettre en place pour arriver à cela :
$(document).ready(function () {
    $('.searchMenu li.dropdown a').click(function (event) {
        $(this).parent().toggleClass("open");
    });

    $('body').click(function (e) {
        if (!$('.searchMenu li.dropdown').is(e.target) &&
            $('.searchMenu li.dropdown').has(e.target).length === 0 &&
            $('.open').has(e.target).length === 0) {
            $('.searchMenu li.dropdown').removeClass('open');
        }
    });
});
 La première partie du script permet de mettre en place la classe "open" sur le menu dropdown permettant d'ouvrir la dropdown, et cela est fait lors du click sur la dropdown.

La seconde partie du script permet de refermer la dropdown (en supprimant la classe "open") sauf dans le cas où l'on clique dans la dropdown.

Avec cela mon problème de menu "Rechercher" est réglé...

jeudi 27 mars 2014

Récupération d'une base de données et rattachement à un utilisateur

Voici un problème que je rencontre systématiquement dès lors que je récupère un backup de base de données pour l'intégrer sur un de mes serveurs. Une fois le backup restaurer sur mon serveur, je souhaite définir un utilisateur pour m'y connecter. Généralement je recrée un user existant déjà dans la base que je viens de restaurer et là je me heurte à une erreur SQL 15023 m'informant que le user existe déjà et que je ne peux donc pas le recréer.

Pour résoudre ce problème je me reporte à ce blog où la solution décrite est simple et efficace :

http://blog.sqlauthority.com/2007/02/15/sql-server-fix-error-15023-user-already-exists-in-current-database/

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.

mercredi 21 novembre 2012

Nivo.Slider et événement "Load" levé 2 fois

Je viens de résoudre un problème auquel j'étais confronté depuis hier sur un de mes projets : l'événément "Load" se levait deux fois sur les pages de mon site. On pourra dire que c'est un problème classique, auquel nous avons tous été confrontés au moins une fois.

Après les vérifications d'usages (AutoEventWireup...), je suis parti à la recherche de cet élément qui faisait que certaines de mes pages levaient deux fois cet événement. Finalement, mon problème venait d'un module utilisant le script JQuery "Nivo Slider".

Me voilà donc parti à décortiquer le script en question... et là je suis tombé sur l'origine du problème. J'utilise la version 3.1 de ce script, ligne 77 du fichier "jquery.nivo.slider.js" j'ai effectué le correctif suivant :
  • à l'origine : var sliderImg = $('');
  • après correction : var sliderImg = $('');
 Après cette modification, la page ne se chargeait d'une seule fois. Je n'ai pas vu d'effet de bords, à voir si cela ne pose pas de soucis sur certains navigateurs (sous fireFox c'est ok).

Pour la version "compressé" de ce script (fichier "jquery.nivo.slider.pack.js"), une recherche sur le texte  "nivo-main-image" devrait vous permettre de retrouver le "coupable".

mardi 2 octobre 2012

Accéder aux informations de la page parente

Un de mes collègue devait réaliser un "petit" module permettant d'afficher sur une page le titre de la page parente. Nous avions une arborescence de page de ce type :
  • Page A
    • Page A.1
Nous souhaitions donc déposer ce module sur la page "A.1" pour y voir apparaitre le titre de la page "A".
Voici un petit script tout simple permettant d'accéder au titre de la page parente :
(TabInfo)PortalSettings.ActiveTab.BreadCrumbs[PortalSettings.ActiveTab.Level - 1].Title

 Merci à Jonathan pour cette information.

Modification du titre d'un module par code

La modification du titre d'un module peut se faire en mode runtime. Par contre il y a deux petites choses à savoir :
  • la propriété à modifier pour effectuer cette modification,
  • dans quel événement placer le code.
Voici le code à utiliser :
this.ModuleConfiguration.ModuleTitle = "Votre titre";

Ce code doit être placé dans l'événement "Init" de votre module sans quoi il ne sera pas pris en compte.

En C#, cela vous donnera quelque chose de ce type :
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);

        this.ModuleConfiguration.ModuleTitle = "Titre du module";
    }

lundi 13 février 2012

Visual Source Safe (VSS) : "Impossible de trouver le fichier SS.INI pour l'utilisateur..."

Voici un problème que vous pouvez rencontrer (pour ma part cela fait 2 fois) avec Visual Source Safe 2005 et Visual Studio 2010. Au lancement de ce dernier, lors du chargement de votre projet, vous obtenez le message suivant :
Impossible de trouvere le fichier SS.ini pour l'utilisateur ...

Surtout pas de panique, comme l'indique ce message, il manque un fichier maintenant reste à savoir où ce fichier doit se trouver.

Et bien voilà la réponse...

Ce problème est tout d'abord un problème sur votre serveur VSS. Il vous faut donc identifier le répertoire de votre projet sur votre serveur VSS, à partir de là vous devez rechercher le répertoire "users" puis le nom de l'utilisateur pour lequel le problème a été levé. Et vous constaterez qu'aucun fichier SS.ini ne se trouve dans ce répertoire. Pour corriger le problème, vous n'avez qu'à récupérer un fichier SS.ini se trouvant dans le répertoire d'un autre utilisateur.

Vous pouvez modifier le contenu de ce fichier pour personnaliser votre VSS, moi personnellement je n'ai pas eu à le faire...

lundi 6 février 2012

Activation du multilangue sur un site DNN 6

Une fois l'installation de votre site DNN 6 effectuée, l'activation du mode multilangue n'est pas forcément des plus simple. En effet deux étapes doivent être effectuée :

  • Activation du mode multilangue au niveau du Host
  • Activation du mode multilangue au niveau du Site
Première étape : activation du mode multilangue au niveau du host :

Pour activer le mode multilangue, vous devez autorisez la traduction des contenus. Cette option se trouve dans le paramétrage du Host dans les "Autres paramètres", option "Autorisez la traduction des contenus".


Seconde étape : activation du mode multilangue au niveau du site :

Pour activer le mode multilangue, après avoir défini la langue par défaut du site (attention, vous ne pourrez plus revenir sur cette option après l'activation), il faut se placer sur la page des langues du site et cliquer sur le lien "Activer le multilinguisme" (duplication des pages à traduire).