mardi 2 juillet 2013

TypeScript

Il y a quelques temps que j'avais entendu parler de ce nouveau langage qui se nomme TypeScript. TypeScript est un langage typé, contrairement au Javascript, qui à la compilation, génère du code Javascript. Il met à la disposition des développeurs web les concepts de la programmation orienté objet. À cette époque, qui n'est pas si lointaine soit dit en passant, je développais principalement en ASP.net et j'avais peu recours au Javascript donc je ne m'y était pas trop attardé.

Un peu plus tard, j'ai dû développer un module sur un Extranet. Le back-end étant un serveur PHP, et moi qui est un néophyte en ce qui concerne le PHP, j'ai donc décidé de coder le maximum du module en javascript et de laisser seulement les opérations BD et la sécurité au serveur PHP. Ce fût un projet assez complexe, j'ai donc dû créer d'énormes fichiers Javascript avec multitudes de variables, prototype, fonctions etc. Bref au final, le résultat fût beaucoup de code éparpillé et dur à maintenir.

TypeScript met donc revenu en tête. Ce langage est conçu pour développer des applications de grande envergure qui permet de regrouper le code sous forme de classes, namespaces, interfaces etc. Offrant les concepts de l'orienté objet, il supporte bien entendu l'héritage. La dernière version 0.9 offre même le support des Generic.

La courbe d'apprentissage

Une des ses forces à mon avis est que la courbe d'apprentissage peut-être vraiment être graduelle. En fait, on peut créer un fichier TypeScript et écrire du code 100% Javascript et ça fonctionne. On peut donc utiliser du code Javascript d'un projet existant et typer certaines variables ou recoder certaines classes. Il est possible de profiter des forces qu'offre TypeScript sans avoir à tout ré-écrire.

Les librairies incontournables

L'utilisation des librairies tel que JQuery, Knockout, LINQ etc. fonctionnent en TypeScript à condition de référencer les fichiers de définitions de la librairie. Ces fichiers décrivent les objets de la librairie, ce qui permet à TypeScript de valider que l'appel à ces objets est bien valide. Les fichiers de définitions des différentes librairies peuvent être trouvé sur Definitely Types ou via NuGet.

Conclusion

Évidemment tout ce qu'on peut faire avec TypeScript, on peut également le faire en javascript car comme je le disait plus haut, la compilation d'un fichier TypeScript (.ts) créer un fichier Javascript. Son but est d'offrir au développeur une syntaxe beaucoup plus simple et le langage typé permet de détecter des erreurs à la compilation au lieu de les découvrir au runtime. Je ne pourrai plus m'en passer en ce qui me concerne! ;)

http://www.typescriptlang.org/

dimanche 18 novembre 2012

NDateTime (DateTime du .NET porté pour JavaScript)

Voilà ma dernière création, une librairie JavaScript qui regroupe les fonctionnalités de base d'un objet DateTime en .NET

Plus besoin de se battre avec les dates JavaScript! :)

Pour tous les développeurs web.
Si vous avez des idées (Ajouts/Commentaires) n'hésitez pas!



http://ndatetime.codeplex.com

dimanche 19 février 2012

Comment ouvrir une nouvelle fenêtre en javascript à la suite d'un postback (ASP.NET)

Il peut paraître assez simple à première vue d'ouvrir une fenêtre en javascript à la suite d'un postback. On aurait tendance à ce dire qu'il suffit d'enregistrer un script avec la commande window.open. Le problème c'est que les navigateurs sont maintenant munis de "Pop-up blocker". Les navigateurs empêchent donc toutes ouvertures de fenêtre en javascript sauf si l'action provient d'un clic sur un lien ou un bouton.

Heureusement, il y a une façon de contourner ce problème. La solution est d'ouvrir la fenêtre sur l'évènement onclick côté client et de lui assigner un nom unique. Ensuite, lorsque vous atteignez l'évènement buttonclick côté serveur, il suffit d'utiliser la commande window.open avec le même nom spécifié côté client. Le navigateur va donc utiliser la même fenêtre ouverte précédemment côté client. De cette façon, on respecte les règles d'ouvertures de fenêtre en javascript des navigateurs.

Voici un exemple très simple, je vous l'accorde, mais qui démontre la solution : Voici le bouton du bouton dans notre fichier aspx
<asp:Button ID="ButtonOpenGoogle" Text="Cliquer pour ouvrir Google" /> OnClick="ButtonOpenGoogle_Click" /> OnClientClick="window.open('about:blank', 'windowPopupGoogle');" />
Voici le code de l'évènement click du bouton côté serveur
Dans l'exemple ci-dessus la fenêtre est identifiée de façon unique avec le nom 'windowPopupGoogle'.

Il peut arriver aussi qu'une fois côté serveur, on veule annuler l'ouverture de la fenêtre, il suffit donc de récupérer le handler de la fenêtre et d'effectuer une window.close telle que dans l'exemple ci-dessous.
 protected void ButtonOpenGoogle_Click(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(this, typeof(Page), "windowPopupGoogleScript", "var win = window.open('about:blank','windowPopupGoogle');win.close();", true);
}
Voilà!

mardi 24 janvier 2012

Comment neutraliser un spambot qui utilise un formulaire web

Un spambot est un logiciel qui permet d'envoyer des pourriels. Il existe plusieurs types de spambots. Certains recherchent des adresses courriel en parcourant des pages web pour ainsi se créer une liste d'adresses et ensuite d'envoyer des pourriels à cette liste. Il en existe également pour les forums, les wikis donc pour les formulaires web en général.

Solution Captcha

Il existe une technologie qui se nomme Captcha (Completely Automated Public Turing test to tell Computers and Humans Apart) qui permet d'effectuer une vérification en utilisant la capacité d'analyse d'image ou de son de l'être humain. Les Captcha visuels fournissent des mécanismes d'altération de l'image (déformation légère, points aléatoires, ligne transversale, etc.) afin que les logiciels de reconnaissance optique de caractères ne puissent pas décoder les caractères sur l'image. Malheureusement, les spambots les plus perfectionnés sont en mesure de contourner les Captcha. Certains Captcha sont tellement déformés pour éviter une reconnaissance automatique que même les internautes ne peuvent les reconnaître.
Exemple de Captcha


Solution Honeypot (Pot de miel)

Il existe une façon que je trouve assez intéressante pour régler ce problème. Il s'agit en gros de tendre un piège aux spambots afin de pouvoir les neutraliser. Les spambots ne sont pas capables de distinguer à quoi servent les champs de votre formulaire. Ils sont capables de détecter les types de champs, mais non leurs fonctions. Les spambots ont l'habitude de remplir de données bidon tous les champs du formulaire web (afin de contourner les RequiredValidator) alors grosso modo le truc est d'ajouter un champ bidon (caché en CSS) afin que l'intru y ajoute des données. Ce champ n'étant pas visible aux utilisateurs "normaux", nous pourrons donc déduire que le formulaire a été saisi par un robot si le champ contient des données et par un utilisateur si le champ est vide.

Dans le l'événement OnInit de la page de formulaire, nous allons ajouter le champ texte bidon et lui assigner une classe CSS afin de pouvoir le cacher. La classe CSS aura un nom généré au hasard au format suivant :
trap + nombre aléatoire de 1 à 1000
Le nom de la classe est généré afin que le spambot ne puisse pas détecter l'astuce.
protected override void OnInit(EventArgs e)
{
base.OnInit(e); //Add a HoneyPot to block spambots //Generate a random class name Random random = new Random();
String honeyPotCssClassName = String.Concat("trap", random.Next(1000).ToString());
TextBox textHoneyPot = new TextBox()
{
ID = "textHoneyPot",
CssClass = honeyPotCssClassName
};
Form.Controls.Add(textHoneyPot);

ClientScript.RegisterClientScriptBlock(typeof(Page), "_dynamiccsstrap", String.Concat("<style type=\"text/css\">.",honeyPotCssClassName," { display:none !important; } </style>"), false);
}
Lors que le formulaire est retourné au serveur, on doit s'assurer que le champ textHoneyPot est vide avant de poursuivre le traitement.
 protected void ButtonSend_Click(object sender, EventArgs e)
{
TextBox textHoneyPot = (TextBox)Form.FindControl("textHoneyPot");
if (Page.IsValid && String.IsNullOrEmpty(textHoneyPot.Text))
{
//Do stuff
}
}

Voilà, le problème des spambots devrait être réglé, du moins jusqu'à la prochaine percée! ;)

dimanche 9 octobre 2011

Comment désactiver un validateur en JavaScript (ASP.NET)

Il y a des scénarios où l'on doit valider ou non certaines section d'un formulaire dépendant des choix fait par l'utilisateur. Lorsqu'un utilisateur fait choix qui affecte la validation d'un formulaire, une des méthodes possible est retourner au serveur (Postback) et d'activer ou de désactiver certains validateurs. Par contre lorsque le formulaire comporte beaucoup de champs, cette option peut s’avérer coûteuse car le tout le Viewstate de la page est transféré au serveur. Dans ce cas, il est possible d'activer ou de désactiver certains validateurs en JavaScript, évitant donc un aller/retour au serveur.

Prenons pour exemple un formulaire qui demande à l'utilisateur son prénom, nom et si l'utilisateur coche la case "J'aimerais m'inscrire à la liste de diffusion." et bien nous l’obligeons aussi à saisir son courriel.
Voici le code HTML du formulaire :

<form id="form1" runat="server">

<div>
<span> Prénom : </span>
<asp:TextBox runat="server" ID="TextBoxFirstName" />
</div> <div>
<span>Nom : </span>
<asp:TextBox runat="server" ID="TextBoxLastName" />
</div>
<div><asp:CheckBox ID="CheckBoxMailingList" Text="J'aimerais m'inscrire à la liste de diffusion." runat="server" onclick="ToggleMailingListSection()" /></div> <div id="MailingListSection">
<span>Courriel : </span> <asp:TextBox runat="server" ID="TextBoxEmail" /> <asp:RequiredFieldValidator ID="RequiredFieldValidatorEmail" ControlToValidate="TextBoxEmail" runat="server" ErrorMessage="Le courriel est obligatoire!" />
</div>
<asp:Button Text="Soumettre" runat="server" />
</form>

Rendu du formulaire sans la case cochée :

Rendu du formulaire avec la case cochée :

Lorsque vous cochez la case CheckBoxMailingList, la fonction ToggleMailingListSection est appelée. Voici le code de la fonction:

<script type="text/javascript">
$(document).ready(function () {
ToggleMailingListSection();
});

function ToggleMailingListSection() {
var checkboxMailingList = document.getElementById("CheckBoxMailingList");
var mailingListSection = document.getElementById("MailingListSection");
if (checkboxMailingList.checked) {
mailingListSection.style.display = "block";
}
else {
mailingListSection.style.display = "none";
}
}
</script>

La fonction ToggleMailingListSection sert à cacher ou afficher la section MailingListSection. Même si la section est cachée en CSS, le validateur est encore actif. Pour désactiver un validateur ASP.NET en JavaScript il suffit d'appeler la fonction ValidatorEnable(validator, enable) accessible via WebResource.axd.

<script type="text/javascript">
$(document).ready(function () {
ToggleMailingListSection();
});

function ToggleMailingListSection() {
var checkboxMailingList = document.getElementById("CheckBoxMailingList");
var mailingListSection = document.getElementById("MailingListSection");
var requiredFieldValidatorEmail = document.getElementById("RequiredFieldValidatorEmail");

if (checkboxMailingList.checked) {
mailingListSection.style.display = "block";
ValidatorEnable(requiredFieldValidatorEmail, true);
}
else {
mailingListSection.style.display = "none";
ValidatorEnable(requiredFieldValidatorEmail, false);
}
}
</script>

Voici en ajoutant les deux lignes ValidatorEnabled, on peut maintenant activer ou désactiver le validateur sans avoir à communiquer avec le serveur!

mardi 13 septembre 2011

Opérateur conditionnel (?:) et opérateur de nulle coalescence (??) en C#

L'opérateur conditionnel et l’opérateur de nulle coalescence peuvent s'avérer très utiles pour simplifier votre code et le rendre également plus lisible.

L’opérateur conditionnel

L'opérateur conditionnel (également appelé opérateur ternaire) permet de d'évaluer une condition et ensuite d'évaluer l'une ou l'autre des parties pour en retourner le résultat. La syntaxe est z ? x : y
Donc dans l'exemple ci-dessous, si la condition est (a==1) est vraie, x sera égal à 1 sinon il sera égal à 0.
int x = (a==1) ? 1 : 0;

Le premier opérande de l'opérateur conditionnel (a==1) doit être une expression d'un type qui peut être converti implicitement en bool ou une expression d'un type qui implémente operator true.
Le type de l’expression conditionnel est déterminé par le deuxième et troisième opérande. En se base sur le modèle suivant :

  • Si y et z sont du même type, il s'agit alors du type de l'expression conditionnelle.
  • Sinon, s'il existe une conversion implicite de X en Y, mais pas de Y en X, Y est alors le type de l'expression conditionnelle.
  • Sinon, s'il existe une conversion implicite de Y en X, mais pas de X en Y, X est alors le type de l'expression conditionnelle.
  • Sinon, le type d'expression ne peut pas être déterminé et une erreur de compilation se produit.

Voir documentation sur MSDN http://msdn.microsoft.com/fr-fr/library/aa691313(v=vs.71).aspx

Donc au lieu d’écrire une expression tel que :
string GetValueName(int value)

{
if (value == 1)
return "Value 1";
else
return "Value 2";
}

On peu tout simplement écrire :
string GetValueName(int value)


{
return (value == 1) ? "Value 1" : "Value 2";
}


L’opérateur de nulle coalescence

Tout d'abord, le mot coalescence signifie grossièrement « Unir 2 parties en une seule, fusionner ». L’opérateur de nulle coalescence vérifie si le premier opérande est non null, si c’est le cas cette valeur est retournée, sinon c’est la valeur du deuxième opérande qui est retourné. La syntaxe est x ?? y
Donc dans l'exemple ci-dessous, si la condition est la variable age n’égale pas à null, la fonction GetAge retournera la valeur de age, sinon elle retournera 0.
int GetAge(Nullable age)

{
return age ?? 0;
}


Vous remarquerez également que la conversion age (Nullable) en int lors du retour de la fonction s’est faite par l’opérateur de nulle coalescence, donc pas besoin de cast.

mardi 12 juillet 2011

Utiliser LINQ to SQL sur une base de données SQL Server Compact Edition (SQL CE)

Il est simple d’utiliser LINQ to SQL afin de se connecter à une base de données SQL Server. Il suffit de faire glisser les tables ou procédures stockées de la fenêtre Server Explorer vers votre fichier DBML. Toutefois lorsque la base de données est de format SQL Server Compact Edition, vous risquez d’avoir un message d’erreur « The selected object(s) use an unsupported data provider. »



Il existe un utilitaire en ligne de commande qui se nomme SqlMetal et qui permet d’outre passer ce problème. Cet outil permet de générer un fichier dbml à partir d’importe quelle base de données (vous devrez vous procurer le provider LINQ to pour les bases de données autres que Microsoft SQL Server). SqlMetal.exe se trouve habituellement dans
C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin


Voici un exemple concret d’utilisation. Nous avons une application avec une base de données HumanResources.sdf qui contient une table Employee. Pour générer notre fichier DBML il suffit d’ouvrir une console de ligne de commande (cmd) et de se positionner dans le dossier de notre projet. Ensuite exécuter la commande

"C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\SqlMetal.exe" /conn:"Data Source=HumanResources.sdf" /dbml:DataClassesHumanResources.dbml /provider:SQLCompact




Vous pouvez maintenant retourner dans Visual Studio et inclure le fichier dbml généré à votre projet.


Pour plus d'information sur SqlMetal : http://msdn.microsoft.com/fr-fr/library/bb386987.aspx

Vous êtes maintenant prêt à utiliser LINQ to SQL sur votre SQL Server Compact Edition!


Notes

Il est également possible d'automatiser cette procédure pour ne pas avoir à refaire ces étapes lorsque que vous modifiez votre base de données. Une façon de faire est d’appeler SqlMetal dans l’évènement Pre-build de votre projet.



La commande de Pre-build pour notre exemple serait :
"C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\SqlMetal.exe" /conn:"Data Source=$(ProjectDir)\HumanResources.sdf" /dbml:$(ProjectDir)\DataClassesHumanResources.dbml /provider:SQLCompact


En espérant que cet article vous ait été utile.