[DXPerience] Mettre en place le routage sur un ASPxNewsControl en ASP.NET 4

By Aymeric on août 8th, 2010

La SEO (Search Engine Optimization) est de plus en plus importante afin de mettre en avant votre site web sur internet via les moteurs de recherche. Pour une explication plus approfondie sur le SEO en ASP.NET 4, consultez la suite d’articles écrite par Nicolas Esprit en suivant le lien suivant.

DevExpress avec ses composants ASP.NET propose un ensemble de contrôles facilitant le développement web. L’un de ces contrôles, l’ASPxNewsControl permet d’afficher facilement une série de news/articles avec gestion de la pagination, extrait, etc…

Pour l’ASPxNewsControl, le but est d’avoir des URL du type http://www.aymericlagier.com/News/1/Titre-de-ma-news au lieu de http://www.aymericlagier.com/News.aspx?id=1 afin d’améliorer la lisibilité sur les moteurs de recherche. Cette modification d’URL passe par la mise en place de routage en ASP.NET.

La 1re étape consiste à définir notre route dans le fichier global.asax de l’application web.

        protected void Application_Start(object sender, EventArgs e)
        {
            RegisterRoutes(RouteTable.Routes);
        }

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapPageRoute("RouteToNews", "News/{newsID}/{newsTitle}", "~/News.aspx");
        }

Ici typiquement, les URL du type http://www.aymericlagier.com/News/1/Titre-de-ma-news pointeront sur la page News.aspx du site web. Le 1 (ID de la news) et Titre-de-ma-news pourront être récupérés dans le code en suivant le même principe que les paramètres passés en GET dans l’URL. Vous pouvez ajouter autant de routes que vous le souhaitez dans la méthode RegisterRoutes.

La 2ème étape consiste à créer l’ASPxNewsControl :

  • Default.aspx :
<pre><dx:ASPxNewsControl ID="ASPxNewsControl1" runat="server" Width="400px"
			NavigateUrlFormatString="~/News/{0}" ClientIDMode="AutoID"
			OnItemDataBound="ASPxNewsControl1_ItemDataBound">
			<ItemSettings DateHorizontalPosition="OutsideLeft" MaxLength="10"
				TailText="Lire la suite">
			</ItemSettings>
			<PagerSettings SEOFriendly="CrawlerOnly"></PagerSettings>
		</dx:ASPxNewsControl></pre>

L’attibut NavigateUrlFormatString indique à l’ASPxNewsControl le format de l’URL à respecter. {0} sera remplacé par /ID/Titre lorsque la news sera liée (bind) via l’événement OnItemDataBound.

Petite astuce, l’attribut SEOFriendly dans les PagerSettings de l’ASPxNewsControl, permet de modifier le comportement de la pagination. En effet, par défaut cette option est désactivée. Le crawler (robot) ne voit pas qu’il y a plusieurs pages puisque la pagination se fait via des callbacks en AJAX. Seule la 1re page est indexée. Mettre l’option sur Enabled (activée), les liens vers les autres pages se transforment en liens hypertextes que le robot peut voir, cependant l’utilisateur perd le bénéfice de l’AJAX. Un compromis existe entre ces 2 options, l’option CrawlerOnly. Pour les utilisateurs la pagnation se fait toujours en AJAX, mais pour les crawlers l’AJAX est remplacé par des liens hypertextes.

3ème étape, remplissage du contrôle avec une liste de news.

  • Classe News
    class News
    {
        public int id { get; set; }
        public string title { get; set; }
        public string content { get; set; }
        public DateTime date { get; set; }
    }
  • Default.aspx.cs
            List<News> li = new List<News>();

            for (int i = 1; i <= 10; i++)
            {
                li.Add(new News() { id = i, title = String.Format("Titre {0}", i), content = String.Format("Mon contenu de la news {0}", i), date = DateTime.Now });
            }

            ASPxNewsControl1.DataSource = li;
            ASPxNewsControl1.TextField = "content";
            ASPxNewsControl1.DateField = "date";
            ASPxNewsControl1.HeaderTextField = "title";

            ASPxNewsControl1.DataBind();

            Session["list"] = li;

La liste est stockée en session pour être utilisée par la suite sur la page News.aspx.

Si le titre de la news comporte des espaces  » « , des guillemets ou autres caractères spéciaux, il faut les convertir avant de les insérer dans l’URL. Le titre « La news du siècle ! » devra être transformée en « La-news-du-siecle » par exemple (suppression des espaces, accents, !, ?, etc….). La classe Routing permet cette opération :

   public class Routing
    {
        public static string ToFriendlyUrl(string urlToEncode)
        {
            urlToEncode = (urlToEncode ?? "").Trim().ToLower();

            StringBuilder url = new StringBuilder();
            string final = "";

            foreach (char ch in urlToEncode)
            {
                switch (ch)
                {
                    case ' ':
                        url.Append('-');
                        break;
                    case '&':
                        url.Append("et");
                        break;
                    case '\'':
                        break;
                    case '!':
                        url.Append("");
                        break;
                    case '?':
                        url.Append("");
                        break;
                    case 'é':
                        url.Append("e");
                        break;
                    case 'è':
                        url.Append("e");
                        break;
                    case 'ê':
                        url.Append("e");
                        break;
                    case 'à':
                        url.Append("a");
                        break;
                    case 'â':
                        url.Append("a");
                        break;
                    case 'ù':
                        url.Append("u");
                        break;
                    case 'û':
                        url.Append("u");
                        break;
                    default:
                        if ((ch >= '0' && ch <= '9') ||
                            (ch >= 'a' && ch <= 'z'))
                        {
                            url.Append(ch);
                        }
                        else
                        {
                            url.Append('-');
                        }
                        break;
                }

                final = Regex.Replace(url.ToString(), "-$", "");
            }

            return final;
        }
    }

4ème étape, la construction de l’URL pour chaque news via l’event handler ASPxNewsControl1_ItemDataBound :

        protected void ASPxNewsControl1_ItemDataBound(object source, DevExpress.Web.ASPxNewsControl.NewsItemEventArgs e)
        {
            News n = (News)e.Item.DataItem;
            e.Item.NavigateUrl = String.Format("{0}/{1}", n.id, Routing.ToFriendlyUrl(n.title));
        }

L’ASPxNewsControl est prêt pour un bon référencement.

Le projet utilisé dans cet article est disponible ici.

[DXPerience] Lier une base de données et un ASPxGridView avec Linq To SQL

By Aymeric on décembre 8th, 2009

Suite de mes articles sur les technologies .NET et DXperience. Le but est ici de lier efficacement une base de données à un ASPxGridView grâce à Linq To SQL graphiquement.

Petite précision, mon OS et mon IDE (Visual studio) sont en anglais, si le votre est en français, vous n’aurez pas exactement les mêmes mots, mais vous vous y retrouverez sans problème.

Voici les étapes et quelques explications concernant le screencast.

  • Créer un nouveau projet web
  • Ajouter un élément : Linq To SQL Classes
  • Glisser/Déposer les tables dont vous avez besoin dans le fichier .dbml
  • Ajouter un ASPxGridView dans votre fichier Default.aspx
  • Ajouter un Datasource Linq Server Mode Source

Il est préférable de choisir un Linq Server mode Source plutôt qu’un LINQ. Il offre de meilleures performances sur les tables contenant un grand nombre de données. Vous pouvez constater par vous même ces performances ici.

  • Enregistrer le projet (Sinon vous aurez des problèmes par la suite)
  • Dans les propriétés du LinqServerModeDataSource, déroulez la liste de la propriété ContextTypeName et indiquez votre DataContext. Pour la propriété TableName, choisissez la table que vous souhaitez voir apparaître dans votre ASPxGridView.
  • Si vous le souhaitez, passez à true les propriétés EnableDelete, EnableInsert et EnableUpdate, pour autoriser la suppression, l’ajout et la modification de données dans cette table.
  • Si vous avez autorisé la modification des données dans le LinqServerModeDataSource, n’oubliez pas d’activer ces fonctionnalités dans l’ASPxGridView.

Pour une utilisation plus poussée, je vous conseille l’excellent screencast de Mehul Harry disponible ici (en anglais).

Vous pouvez télécharger le projet utilisé en cliquant ici.

[DXPerience] Créez des onglets en ASP.NET/C# avec DXperience

By Aymeric on octobre 21st, 2009

Voici le premier article (d’une longue liste j’espère) sur DXperience, ensemble d’outils pour développer en ASP.NET C# ou VB. La difficulté des articles sera croissante, en effet, je débute avec cet outil, les premiers articles traiteront donc de fonctionnalités simples.

Pour comprendre et utiliser cet article, il faut avoir acheté et installé DXperience sur son système d’exploitation.

Le but de cet article est de montrer la création d’onglets sur une page web.

Pour commencer, créez un nouveau projet ASP.NET/C# dans Visual Studio.

création projet VS

Dans la « Boîte à outils », glissez-déposez un « ASPxPageControl »  sur votre page: ASPxPageControl

Les balises <dxtc:ASPxPageControl ></dxtc:ASPxPageControl> ont été générées automatiquement.

Avant de continuer, remarquez qu’une nouvelle ligne est apparue en haut de votre fichier :

<%@ Register Assembly="DevExpress.Web.v9.1, Version=9.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"
    Namespace="DevExpress.Web.ASPxTabControl" TagPrefix="dxtc" %>

Il s’agit du namespace contenant l’élément que l’on vient d’ajouter. Pour continuer, il nous faut en rajouter un autre manuellement. Ajouter en dessous de la ligne ci-dessus le code suivant :

<%@ Register Assembly="DevExpress.Web.v9.1, Version=9.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"
    Namespace="DevExpress.Web.ASPxClasses" tagprefix="dxw" %>

La création des onglets à proprement parler commence ici, pour ajouter un onglet, ajouter le code suivant entre les balises <dxtc:ASPxPageControl></dxtc:ASPxPageControl> :

            <TabPages>
               <dxtc:TabPage Text="1er onglet">
                   <ContentCollection>
                      <dxw:ContentControl runat="server">
                          Contenu de mon 1er onglet
                      </dxw:ContentControl>
                   </ContentCollection>
               </dxtc:TabPage>
            </TabPages>

Pour ajouter un second onglet, ajouter après </dxtc:TabPage> le code suivant :

               <dxtc:TabPage Text="2eme onglet">
                   <ContentCollection>
                      <dxw:ContentControl runat="server">
                          Contenu de mon 2eme onglet
                      </dxw:ContentControl>
                   </ContentCollection>
               </dxtc:TabPage>

Vos onglets sont créés, voici le résultat :

Résultat

Vous remarquerez qu’un nouveau namespace est déclaré dans votre fichier :

<%@ Register Assembly="DevExpress.Web.ASPxEditors.v9.1, Version=9.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"
    Namespace="DevExpress.Web.ASPxEditors" TagPrefix="dxe" %>

Comme toujours en ASP.NET de nombreuses options sont disponibles pour « customizer » vos onglets, par exemple les propriétés Height et Width qui permettent de modifier la taille de la TabPage. Voici un exemple :

        <dxtc:ASPxPageControl ID="ASPxPageControl1" runat="server" Height="500px" Width="400px">
            <TabPages>
               <dxtc:TabPage Text="1er onglet">
                   <ContentCollection>
                      <dxw:ContentControl runat="server">
                          Contenu de mon 1er onglet
                      </dxw:ContentControl>
                   </ContentCollection>
               </dxtc:TabPage>
               <dxtc:TabPage Text="2eme onglet">
                   <ContentCollection>
                      <dxw:ContentControl ID="ContentControl1" runat="server">
                          Contenu de mon 2eme onglet
                      </dxw:ContentControl>
                   </ContentCollection>
               </dxtc:TabPage>
            </TabPages>
        </dxtc:ASPxPageControl>

ce qui donne :

Tab 500x400px