Wilfried Woivré & .Net

Créer des urls propres pour vos sites Web

AVRI29

Si comme moi, vous aimez voir des urls lisibles quand vous naviguez sur des sites, vous vous êtes déjà penchez sur la question sur comment formater votre url, afin qu’elle soit facilement lisible pour vos utilisateurs, et pour les moteurs de recherche.

 

Alors comme vous devez le savoir il y a la méthode UrlEncode disponible dans le Framework, mais personnellement je n’aime pas trop cette méthode, puisqu’elle vous traduit les caractères spéciaux en caractères encodés, ce que je ne trouve pas très lisible.

L’autre solution est de remplacer tous les caractères spéciaux par un autre caractère associé, en créant 2 listes, et en réalisant un mapping, mais il suffit que vous oubliez un caractère spécial, et c’est le drame !

 

La dernière solution, c’est de réaliser une normalisation de votre chaîne de caractères, et de garder uniquement les caractères qui vous intéressent, voici donc la méthode que j’utilise pour mon blog :

 

public static string GenerateShortName(this string valueToConvert)
{
    StringBuilder sb = new StringBuilder();
    string st = valueToConvert.ToLower().Normalize(NormalizationForm.FormD);

    foreach (char t in st)
    {
        System.Globalization.UnicodeCategory uc = System.Globalization.CharUnicodeInfo.GetUnicodeCategory(t);
        switch (uc)
        {
            case System.Globalization.UnicodeCategory.LowercaseLetter:
            case System.Globalization.UnicodeCategory.DecimalDigitNumber:
                sb.Append(t);
                break;
            case System.Globalization.UnicodeCategory.SpaceSeparator:
                if (sb.ToString().LastOrDefault() != '-')
                    sb.Append('-');
                break;
            default:
                break;
        }
    }

    string value = sb.ToString().Normalize(NormalizationForm.FormC);

    return value;
}

Alors si on prend comme exemple le texte suivant : “Unity : Gestion des paramètres primitifs”, regardons ce que ça donne lorsqu’on l’encode, où que l’on utilise cette méthode.

image

A mon sens, le résultat est sans appel, mais je ne suis pas  à 100% objectif !

Et voilà, même près tout ce temps, le Framework .Net peut vous apprendre énormément de choses !

Remonter

Nouveautés C# 5 : Mots clef async et await

OCTO29

 

Et voilà, la PDC a débuté aujourd”hui même, c’est donc le moment de faire le plein de nouveautés, entre autre sur Windows Azure, mais on en reparlera dans un autre article sur ce blog, ou sur ZeCloud !!

Il y a bien entendu d’autres nouveautés, mais bon ça a commencé il y a juste 6h à l’heure où j’écris cet article, dont des nouveautés sur C# 5, et les méthodes asynchrones !!

 

Alors vu que du code en dit toujours plus long que des belles paroles, prenons l’exemple d’une méthode asynchrone classique :

public void BeforeAsync()
{
    var client = new WebClient();
    client.DownloadStringCompleted += (sender, e) => ParseRss(e.Result);
    client.DownloadStringAsync(new Uri("http://blog.woivre.fr?feed=rss2"));
}

 

Et on parse notre fichier XML de façon assez simple :

 

private void ParseRss(string rss)
{
    XDocument xdoc = XDocument.Parse(rss);

    var titles = from e in xdoc.Root.Descendants("item")
                 select e.Element("title").Value;

    foreach (String title in titles.Take(4))
        Console.WriteLine(title);
}

Voilà jusque là, c’est comme cela qu’on pouvait faire pour récupérer un flux RSS, bon certes si on ne connait pas SyndicationFeed ….

Cependant, comme toute chose à une fin, des nouveautés arrivent, et avec elle le mot clef async, qui va nous simplifier la syntaxe de notre appel en une simple ligne :

public async void WithAsync()
{
    ParseRss(await new WebClient().DownloadStringTaskAsync(new Uri("http://blog.woivre.fr?feed=rss2")));
}

Donc on peut voir en rouge (grâce à Visual Studio qui ne comprend encore rien) que l’on a ajouté deux mots clefs qui sont async et await. Pour faire simple, async va déclarer une méthode comme ayant un fonctionnement asynchrone, et le mot clef await va demander au programme d’attendre le retour de notre fonction avant d’effectuer la suite des opérations. On utilise de plus un DownloadStringTaskAsync à la place du DownloadStringAsync puis ce premier est fourni par le framework Async CTP, et permet de retourner un objet lorsque l’opération est terminée.

 

Alors vu que de toute façon, la vie ne se déroule pas sur un seul Thread, on peut jouer avec plusieurs Thread sans aucun soucis en utilisant le Parallel Framework et Async CTP:

public async void WithAsyncAndParallel()
{
    Task<string> blogWoivre = new WebClient().DownloadStringTaskAsync(new Uri("http://blog.woivre.fr?feed=rss2"));
    Task<string> blogZeCloud = new WebClient().DownloadStringTaskAsync(new Uri("http://www.zecloud.fr/syndication.axd"));

    ParseRss(await blogWoivre);
    ParseRss(await blogZeCloud);
}

 

Voici, donc le résultat final de l’application en ce qui concerne les données, on ne perd à priori aucun temps d’exécution, il faudra cependant tester sur un plus grand jeu de données que le simple flux Rss de ce blog

 

image

Et voilà, encore un peu de sucre syntaxique, mais c’est tellement bon de ne plus se prendre la tête sur ce genre de truc ! Bref ça surpoutre ^^

 

Quelques liens : Async CTP

Blog de Matthieu Mezil qui a posté avant moi, et dont j’ai honteusement piqué le nom des méthodes : http://blogs.developpeur.org/matthieu/archive/2010/10/28/async-et-await-l-asynchrone-avec-c-5-a-surm-gapoutre.aspx

Un peu de ressources anglo saxonne : http://blogs.msdn.com/b/ericlippert/archive/2010/10/28/asynchrony-in-c-5-part-one.aspx

Et les sources, bien entendu !!!

image

Remonter

Attribuer un alias à une classe

JANV22

 

Dans la création de gros site ASP.Net, on se retrouve souvent avec des sites qui contiennent de nombreuses pages ou UserControl, pour éviter que notre projet devienne ne soit dévasté par la pollution de page ou UserControl, il faut créer des dossiers et des sous dossiers pour qu’on puisse facilement si retrouver.

 

On va donc classiquement créer un dossier User qui regroupera toutes les pages et user control concernant les utilisateurs du site. Jusque là rien de bien surprenant, on va créer une page du type de celle-ci :

namespace WebApplication3.User
{
    public partial class EditUser : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
    }
}

On a donc bien dans notre page WebApplication3.User.EditUser, on va donc vouloir récupérer notre utilisateur à éditer, qui est un objet de type User, on va donc commencer par appeler notre objet métier en créant une méthode GetUser, et là on a un problème, en effet notre entité User n’est pas trouvé, mais il trouve un namespace.

image

Ceci est donc parfaitement normal puisqu’il n’y a pas de référence et using vers ce objet de type métier dans notre cas pour le moment, cependant Visual Studio ne nous le propose pas contrairement à d’habitude. On va donc l’ajouter à la main…

 

Mais là même erreur, en effet Visual Studio est totalement perdu, il ne sait pas s’il s’agit d’un type ou d’un namespace. Et pourtant à cet endroit du code, un namespace serait légèrement mal placé.

On a donc 2 solutions qui s’offrent à nous, soit passé par le nom complet, soit ici Entities.User, soit ajouter un alias dans les using :

using EntityUser = Entities.User;

namespace WebApplication3.User
{
    public partial class EditUser : System.Web.UI.Page
    {
        public EntityUser GetCurrentUser()
        {
            throw new NotImplementedException();
        }

Notre application compilera donc sans soucis, on a juste ajouté un alias à la classe Entities.User afin que notre Visual Studio ne soit pas chamboulé par tous ces noms de classes, namespaces ou on n’a jamais d’idée pour les nommer.

Remonter

C# 4.0 : Le mot clef dynamic et la Reflexion

NOVE4

Comme vous avez du en entendre parler une des grandes nouveautés de la version 4 du framework est le mot clef dynamic. Celui-ci permet de simplifier l’utilisation de la réflexion dans les applis .Net.

On va voir dans cet article les différentes façon d’utiliser la réflexion entre la 2.0 et la 4.0. Pour l’exécution de ces diverses méthodes, nous allons utiliser la réflexion sur une DLL, réalisé en F#, dont le contenu fortement complexe est le suivant :

 

module Module1

type Multiplication(val1, val2) =
    let result = val1 * val2
    member obj.Result = result

 

Commençons donc par le tout début, c’est à dire avec un bon vieux InvokeMember, comme on peut le voir ci-dessous :

Type Module = Assembly.LoadFrom("CalcLibrary.dll").GetType("Module1");
Type Multiplication = Module.GetNestedType("Multiplication");
object multiplication = Activator.CreateInstance(Multiplication, new object[2] { val1, val2 });
PropertyInfo propertyResult = multiplication.GetType().GetProperty("Result");
txbResult.Text = propertyResult.GetValue(multiplication, null).ToString();

On obtient donc dans notre jolie interface le bon résultat comme on peut le voir aussi, et heureusement j’ai envie de dire :

 image

Bon malgré le fait que cette réflexion ne soit pas trop poussé, on se rappelle tout de suite que c’est toujours très verbeux. Heureusement, le mot clef dynamic arrive.

 

On voit donc qu’on charge toujours notre DLL, que l’on crée une instance, non pas cette fois dans une variable de type object, mais de type dynamic, grâce à laquelle on a directement accès à la propriété Result.

 

Type Module = Assembly.LoadFrom("CalcLibrary.dll").GetType("Module1");
Type Multiplication = Module.GetNestedType("Multiplication");
dynamic multiplication = Activator.CreateInstance(Multiplication, new object[2] { val1, val2 });
txbResult.Text = multiplication.Result.ToString();

Et notre fenêtre donne toujours le bon résultat :

image

Bien entendu, le mot clef dynamic est à utiliser à bon escient, mais je suppose que je n’ai pas besoin de vous le rappeler ! Donc surtout dans les phases de réflexion, et l’interopérabilité avec le monde COM

Donc pas de solution cette fois-ci encore, tout le code est là ! Je tâcherais de vous faire une petite présentation de F# bientôt (si j’ai un peu de temps …)

Remonter

Silverlight 3.0 et les .Net RIA Services

AOÛT12

Dans la continuité d’un de mes articles sur Silverlight et les différents moyens d’accéder aux données soit via l’utilisation du JSon, ou par des services Web (WCF …). Il en manquait inévitablement un sur les .Net RIA Services. Alors les .Net RIA Services en deux mots, qu’est-ce que c’est, c’est une nouvelle mouture d’ADO.Net pour Silverlight. En effet, lors de la conception d’application Silverlight, on avait vu que cela péchait pour récupérer les données, vu que Silverlight est une technologie cliente. Il fallait donc, comme le montre le schéma ci-dessous  pour accéder aux données contenues dans notre base depuis notre interface, passer par le code métier et ensuite, via un service arrivé à notre base de données pour effectuer la requête. C’est donc ce que l’on appelle une architecture n-tiers, facile à implémenter et facilement maintenable. image Cependant ce découpage est bien souvent pas respecté pour beaucoup de projets, il n’est donc pas rare de voir les différentes parties clientes mélangées, ainsi que le côté serveur pour des questions de rapidité de développement. On a donc généralement une architecture de ce type pour finir. image Cette facilité de développement, j’avoue peut être intéressante dans l’instant lorsque l’on n’a absolument pas l’habitude de bien séparer les diverses couches d’une application, ou que l’on ne veut pas implémenter de Design Pattern (comme le MVVM) dans son projet en plus. Néanmoins, la reprise de tel projet par la suite est d’autant plus dur … Alors maintenant, voyons comment nous structurons nos données avec .Net RIA Services image Bon maintenant que nous avons vu comment est construit une application Silverlight utilisant les .Net RIA Services, on va pouvoir en faire une. Alors pour base de données, je vais prendre celle de NorthWind non modifié, vous pouvez la trouver à ce lien si vous ne l’avez pas. Alors pour commencer nous allons créer une nouvelle application Silverlight de type Business Application. Ce type d’application est ajouté après avoir installer les .Net RIA Services. Maintenant que notre projet est créé, nous allons accéder à notre base, donc dans notre projet ASP.Net, nous allons créer cet accès avec Entity Framework,  avec lequel nous allons récupérer tous les employés de la base Northwind. Donc jusque là, rien de bien anormal par rapport à un autre projet Silverlight que vous auriez pu faire avant. Maintenant, toujours dans le projet ASP.Net, nous allons créer un nouvel item qui s’appelle “Domain Service Class”, on peut le trouver dans la partie Web, comme on peut le voir ci dessous : image Maintenant, nous avons un deuxième écran qui nous demande quels éléments seront disponibles du côté client. Pour la démonstration, nous allons donc choisir les “Employees”, et la possibilité d’éditer ceux-ci. image Cette classe nous génère donc entre autre ce code ci :
    // Implements application logic using the NorthwindEntities context.
    // TODO: Add your application logic to these methods or in additional methods.
    [EnableClientAccess()]
    public class NorthwindDomainService : LinqToEntitiesDomainService<NorthwindEntities>
    {

        // TODO: Consider
        // 1. Adding parameters to this method and constraining returned results, and/or
        // 2. Adding query methods taking different parameters.
        public IQueryable<Employees> GetEmployees()
        {
            return this.Context.Employees;
        }

        public void InsertEmployees(Employees employees)
        {
            this.Context.AddToEmployees(employees);
        }

        public void UpdateEmployees(Employees currentEmployees)
        {
            this.Context.AttachAsModified(currentEmployees, this.ChangeSet.GetOriginal(currentEmployees));
        }

        public void DeleteEmployees(Employees employees)
        {
            if ((employees.EntityState == EntityState.Detached))
            {
                this.Context.Attach(employees);
            }
            this.Context.DeleteObject(employees);
        }
    }
}
Comme on peut le voir, cette action nous permet de générer tous ce qu’il faut pour lire et modifier des employés de la base, bien entendu rien ne vous empêche d’en rajouter, pour des questions de performances, comme par exemple, une partie qui ne retourne seulement 10 employés de la base au lieu de toute la base. L’autre partie qui est généré sont les metadatas nécessaire pour le bon fonctionnement de la communication avec les .Net RIA Services. Donc maintenant qu’on a crée notre partie accès aux données, ainsi que notre code métier, et le service pour accéder à nos données, nous n’avons plus qu’à gérer le côté client en Silverlight. Alors commençons par la partie XAML, pour notre exemple, nous allons afficher les noms et les prénoms des employés de la base de données :
                <ListBox ItemsSource="{Binding}" Margin="0,50,0,0" Height="300">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal" >
                                <TextBlock Text="{Binding FirstName}"
                           Width="250" />
                                <TextBlock Text="{Binding LastName}" />
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
Nous allons maintenant charger les données depuis la base grâce aux RIA Services :
private void Page_Loaded(object sender, RoutedEventArgs e)
{
    var context = new NorthwindDomainContext();
    DataContext = context.Employees;
    context.Load(context.GetEmployeesQuery());
}
Nous chargeons les données de façon assez simple, grâce à une requête Linq, ou à la méthode context.GetEmployeesQuery() qui renvoie ceci :
public EntityQuery<Employees> GetEmployeesQuery()
{
    return base.CreateQuery<Employees>("GetEmployees", null, false, true);
}
Soit toutes les données de la table Employees. Bien entendu, toutes ces opérations avec .Net RIA Services sont asynchrone afin que l’application reste fluide pour l’utilisateur. Alors pour conclure sur cet article, et sur cette technologie, les .Net RIA Services sont très puissant pour toutes les applications Business, néanmoins la faille que je vois par rapport à un service classique en WCF, c’est que les .Net RIA Services sont orientés uniquement pour Silverlight, alors qu’un service WCF permet de partager l’accès aux services entre divers types d’application. Voilà bien entendu je vous fournis le code source de l’application, il faudra bien entendu changer la chaine de connexion à la base de données. image Ressouces : Un très bon lien sur .Net RIA Services que je vous conseille : http://blogs.msdn.com/brada/archive/tags/RIAServices/default.aspx
Remonter