vendredi 21 août 2009

Formations Microsoft à des prix TRES préférentiels !!

Les températures grimpent, nos prix baissent !

imageimage

Microsoft et Bewise vous proposent de profiter de cette fin d’été pour former vos collaborateurs aux sujets suivants :

  • Découverte de Windows Azure
  • Développement parallèle avec ParallelFX 4.0
  • Nouveautés SQL Server 2008
  • Découverte de .Net 4.0 et Visual Studio 2010
  • Utilisation avancée de Silverlight
  • Utilisation avancée de WPF
  • Découverte de Silverlight
  • Découverte de WPF

· Date : chacune de ces formations sera donnée sur septembre et/ou octobre 2009

· Durée : 3 jours chacune

· Lieu : chez Bewise ou dans vos locaux

· Formateur – consultant : certifié Microsoft Certified Trainer (MCT)

· Financement : Bewise est centre de formation agréé pour une prise en charge par vos OPCA

· Prix : 490 € HT par stagiaire pour les 3 jours de formation !!!!

Contactez-nous au 05 61 75 13 13 pour connaitre les dates précises de la formation qui vous intéresse et les places disponibles !

jeudi 6 août 2009

Localisation avec ASP.NET MVC

Et oui, je suis encore en train de m'amuser avec la preview de MVC 2. A force de découvrir de nouvelles fonctionnalités qui roxent toutes plus les unes que les autres, je m'étais fait à l'idée que MVC était parfait…

Jusqu'à la nuit dernière, où j'ai fait un cauchemar : je devais gérer la localisation dans un site web, et je ne savait pas comment faire ! En effet, si ASP.NET gère très facilement la localisation sur les contrôles serveur, avec MVC on a tendance à ne pas les utiliser, et l'outil de génération des fichiers de ressources, même s'il est toujours présent, ne génère donc rien. Je me suis donc levé, ai rallumé mon ordinateur, et me suis penché sur la question.

Eh bien, je ne vais pas faire durer le suspens plus longtemps, la gestion de la localisation avec MVC n'est pas beaucoup plus compliquée qu'avant. En effet, si les fichiers de ressource ne sont pas générés automatiquement, rien ne nous empêche de les créer nous même et de les appeler dans nos pages.

J'ai donc créé un fichier Strings.resx, Strings.fr.resx et Strings.en.resx ; dans lequel j'ai mis une chaine de caractère nommée "Texte1", que j'ai traduite en anglais et en français.
Dans la page aspx, pour afficher mon texte localisé, c'est tout simple :
  <%= Strings.Texte1 %>
Ceci affiche donc mon texte dans la bonne langue, en fonction de la culture sélectionnée. Rien de bien compliqué, donc…

Là où je me suis un peu plus creusé la tête, c'est quand j'ai voulu donner à l'utilisateur la possibilité de changer de langue. Encore une fois, c'est pas plus compliqué qu'en ASP.NET classique. N'oublions pas que dans ASP.NET MVC, il y a ASP.NET : une ViewPage MVC est une page comme une autre !
Pour changer la culture d'une page, il suffit de changer la culture du thread courant dans la méthode InitializeCulture() de la page.
Mais comment faire ici, puisque avec MVC on n'a plus de code behind ? Eh bien, tout simplement en changeant la page de base. Dans les directives de mes pages aspx, j'ai changé ça:
<%@ Page Inherits="System.Web.Mvc.ViewPage" %>
par :
<%@ Page Inherits="MvcTools.BasePage" %>

Avec ma classe BasePage qui hérite de ViewPage et qui redéfinit le InitializeCulture() :

image

Dans cet exemple, on vérifie au chargement de la page si la culture est sauvegardée en session, si elle n'existe pas on définit une culture par défaut ; puis on change la culture du thread courant. Il suffit de faire ça pour qu'au chargement de notre page aspx le bon fichier de ressource soit chargé.

Ensuite, pour que l'utilisateur puisse changer de ressource, c'est tout simple : on est en MVC, on crée donc une action dans notre contrôleur qui va changer la culture. Puisqu'on a défini la culture dans la Session, on y a directement accès depuis le contrôleur pour le mettre à jour :

mercredi 5 août 2009

Utiliser les DataAnnotations avec LinqToSql

ASP.NET MVC 2 est arrivé avec une nouveauté très pratique : la validation de données par DataAnnotation. Le principe : on définit sur notre modèle les contraintes à vérifier, et MVC se charge de faire les vérifications (côté serveur uniquement dans la première preview, et normalement une vérification client devrait être générée à l’aide de jQuery dans les prochaines versions).

Par exemple, j’ai la classe suivante :

    public class Contact
    {
       
public String Login { get; set; }
       
public String Email { get; set; }
       
public Int16 Age { get; set; }
    }

Je vais pouvoir lui ajouter les règles de validation de cette manière (sans oublier de référencer System.ComponentModel.DataAnnotations) :

    public class Contact
    {
        [
Required(ErrorMessage="The login is required")]
        [
StringLength(20, ErrorMessage="Must be less than 20 characters")]
       
public String Login { get; set; }

        [
Required(ErrorMessage="The e-mail is required")]
        [
RegularExpression(@"([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})",ErrorMessage="Incorrect e-mail address")]
       
public String Email { get; set; }

        [
Range(0,120)]
       
public Int16 Age { get; set; }
    }

Par contre, un problème se pose lorsque notre modèle provient de code généré. Si on veut annoter nos classes, toutes nos règles de validations disparaitront si on regénère le code.

Heureusement, les p’tits gars de chez Microsoft ont pensé à tout, et nous ont fourni un système pour mettre nos annotations dans une classe partielle :

[MetadataType(typeof(ContactMD))]
public partial class Contact
{

   
private class ContactMD
    {
        [
Required(ErrorMessage = "The login is required")]
        [
StringLength(20, ErrorMessage = "Must be less than 20 characters")]
       
public String Login { get; set; }

        [
Required(ErrorMessage = "The e-mail is required")]
        [
RegularExpression(@"([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})", ErrorMessage = "Incorrect e-mail address")]
       
public String Email { get; set; }

        [
Range(0, 120)]
       
public Int16 Age { get; set; }
    }
}

Ici, la classe Contact a été générée par LinqToSql, et contient les propriétés Login, Email et Age. Je ne peux donc pas les remettre dans la classe partielle.
Il faut dans ce cas créer une autre classe, ContactMD, qui contient les mêmes propriétés que Contact, et sur laquelle on mets nos annotations.
Et on ajoute une annotation MetadataType sur notre classe Contact pour définir dans quelle classe se trouvent les annotations.

mardi 4 août 2009

ASP.NET MVC, Ajax, et XHTML : on ne plaisante pas avec la validité du code !

Update : Avec la preview 2, le problème est malheureusement toujours présent.

Si vous êtes tombé ici en cherchant comment faire de l’Ajax avec ASP.NET MVC, je vous conseille d’aller voir cet article sur Tech Head Brothers : L’AjaxHelper de ASP.NET MVC


Ce post est une réaction à chaud après avoir perdu quelques heures à comprendre pourquoi mon appel Ajax ne fonctionnait pas.

Je viens d’installer la preview d’ASP.NET MVC 2, et après avoir découvert avec enthousiasme les nouveautés, j’ai décidé de tester les Ajax Helpers que je n’avais pas encore pris le temps de regarder dans la première version.

J’ai donc décidé de faire un moteur de recherche asynchrone : une textbox, un bouton pour valider, et une zone avec les résultats qui se mettra à jour toute seule sans recharger la page :

    <div class="search">
   
<p>Recherche d'article</p>
   
<p><% using (Ajax.BeginForm("AjaxSearch", "Search",
           new AjaxOptions() { UpdateTargetId = "searchResult" }))
          {%>
           <%= Html.TextBox("s") %>
          
<input type="submit" value="Search"/>
           <%} %>
</p>
           
      
<p id="searchResult"></p>
   
</div>

Le fonctionnement est très simple : on utilise un formulaire qui fera un appel Ajax, qu’on initialise à l’aide du Ajax.BeginForm
On lui passe en paramètre le nom de l’action et du contrôleur MVC qu’on veut appeler, ainsi que les AjaxOptions : ici je demande à ce que le résultat mette à jour l’élément avec l’id “searchResult”, situé un peu plus bas.

Coté serveur, j’ai donc une action qui va me renvoyer une liste d’articles correspondant à la recherche :

    public ActionResult AjaxSearch()
    {
       
String s =  Request["s"];

       
var data = Context.Articles.Where(a => a.Title.Contains(s)).ToList();

       
if (data.Count == 0)
           
return Content("No article found");

       
return View(data);
    }

Et cette action renvoie une vue, qui est ici une vue partielle (ascx) :

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<MyMvcWiki.Models.Article>>" %>
<ul>
    <%
foreach (var item in Model)
       { %>    
  
<li>
   <%
= Html.ActionLink(item.Title, "Details", "Wiki", new { id=item.Id }, null) %>
  
</li>
    <% } %>
</ul>

Et voilà, Ajax avec MVC, c’est pas plus compliqué que ça !
Enfin, en théorie, puisqu’il suffit de tester la page pour avoir une belle erreur, avec un message très explicite afin de faciliter le débugage :
“Error: Unknown runtime error”
Erreur d’autant plus incompréhensible que lorsque la recherche ne renvoie aucun résultat, le message “No article found” s’affiche correctement.

Je me suis donc arraché les cheveux sur cette erreur, puisque le code me semblait parfaitement correct de bout en bout, jusqu’à ce que je comprenne ce qui n’allait pas.
Revoyons de plus près ce qui se passe coté client :
On fait un appel Ajax qui va mettre à jour ma page. La réponse du serveur doit mettre à jour l’élément avec l’id “searchResult”. Dans mon code, il s’agit d’un élément <p>.
La réponse du serveur renvoie une liste d’articles sous forme de liste à puces <ul> <li>.
Et si on se décide à lire les spécifications du xhtml, on se rend compte que c’est interdit. Et oui, un paragraphe ne doit pas contenir d’éléments de type bloc, donc pas de <ul>…
Il suffit de remplacer mon <p id=”searchResult”> pas un <div id=”searchResult”> pour que ça fonctionne !

Je suis partagé sur cette erreur : d’un coté, c’est vrai que c’est bien de forcer les développeurs à faire du code correct, mais j’aurais quand même apprécié avoir un message d’erreur plus explicite.

En dehors de ça, j’avoue que je suis conquis pas les méthodes Ajax fournies avec MVC. Les accrocs à l’UpdatePanel ne seront pas dépaysés (enfin, pas plus qu’ils ne l’étaient en passant de WebForms à MVC). C’est très facile et rapide à mettre en place, sans avoir à écrire de javascript. Tout en laissant la possibilité aux fans de JavaScript de faire leurs appels Ajax à la main (avec jQuery par exemple, qui est inclut de base dans les nouveaux projets MVC).

Découvrez Vertice Design

Vertice Design est un studio graphique spécialisé dans le design et l'ergonomie d'applications web, windows et mobile.vertice-design
Les équipes maîtrisent des outils variés tels que la gamme Expression de Microsoft, la gamme CS4 d'Adobe, 3ds Max, Nova...
En plus de la réalisation d'interfaces graphiques originales et à votre image, Vertice Design propose des formations afin d'acquérir des compétences
sur des logiciels tels que Expression Web, Blend, Silverlight, Flash, Expression Design, Illustrator...
N'hésitez pas à aller visiter leur site internet pour en savoir plus : http://www.verticedesign.com