mardi 28 décembre 2010

IndexOutOfRangeException: Index xx non valide - Nhibernate

Bonjour,

La gestion de Nhibernate est très complexe ... et je me permet de noter l'erreur suivante qui intervient lors d'un Update :

System.IndexOutOfRangeException: Index 29 non valide pour ce OracleParameterCollection avec Count=29

C'est erreur est lié a la mise a jour de trop de champs (champs en doublons dans le fichier hbm.xml : mapping de Nhibernate). C'est souvent le cas lorsque vous avez un many-to-one pour une assoc et qu'il existe également une property sur le même champs.

A ce niveau la, Nhibernate ne sait pas quel champs prendre, il utilise donc les deux ... et plante joyeusement ^^.


[...]


Dans mon cas, 29 correspond au nombre de champs (property) mappées dans mon fichier xml.

Pour résoudre le problème, deux solutions sont disponibles :
1- Rajouter les attributs update="false" insert="false" sur la/les property

2- Supprimer soit le/les many-to-one soit la/les property


Bonne journée

lundi 30 août 2010

Incorporer une ressources dans une DLL

Bonjour,

Petit billet pour expliquer comment incorporer n'importe qu'elle type de ressources (image, javascript, ...) dans un DLL puis en faire l'appel.

Problème : Comment faire si l'on a plusieurs sites web qui font appel à des même images et script en évitant la répétition ? (copier/coller)

1er élément : le mettre sur un serveur disponible n'importe ou. Du type Google (http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js), qui en interne (en entreprise) n'est pas spécialement le bon choix, on s'orientera plus sur le meme exemple avec nos propres serveurs du style : http://entreprise.intern.fr/ajax/libs/jquery/1.4.2/jquery.min.js.

Cette solution fonctionne parfaitement, mais ce n'est pas celle que j'ai retenu d'expliquer en détails. Le 2nd élément est la mise en place d'une DLL contenant les divers images, scripts nécessaire pour les sites web.

Pour cela nous avons besoins de 2projets (ils peuvent être dans la meme solution ou non).
1. ClassLibrary (bibliothèque de classes)
2. SiteMvc

Dans - ClassLibrary - ajouter une image a la racine du projet (ici worms.jpg) :
Dans les propriétés de l'image (ou de n'importe quelles ressources), changer l'action de génération de "Contenu" en "Ressource incorporée" ! Cette étape est obligatoire !
Ensuite, ajouter une nouvelle classe au projet ClassLibrary (ou ouvrir celle par défaut : Class1.cs). Ajouter en entête de classe :
[assembly: System.Web.UI.WebResource("ClassLibrary.worms.jpg", "image/jpg")]
namespace ClassLibrary
{
    public class Class1
    {

    }
}
Attention, la casse et le namespace/dossier sont très important, sinon depuis vos autres projets vous ne pourrez pas faire l'appel correctement !
Compiler votre 1er projet, il ne doit pas avoir d'erreur.

Maintenant sur votre 2nd projet, ajoutez la référence vers votre DLL ainsi créer. Et depuis l'une de vos vue, ajouter le code suivant pour faire appel a notre image (worms.jpg)

< img src="< % = ClientScript.GetWebResourceUrl(typeof(ClassLibrary.Class1), "ClassLibrary.worms.jpg") % >" / > 

Compilez/Exécuter, tadaaaaaaaa magique l'image des Worms s'affiche sur votre navigateur. Si vous regardez dans le source de la page vous devriez voir l'url peu commune :

< img src="/WebResource.axd?d=haVvUhxQKye3YgyVc9g8l32EYKRgja8RJmuPLLUPaamPyZ8Eyx76lCDu-nUPvlKb0&t=634187628689941128" / >

Voila, c'est tout pour l'instant, j'espère que vous avez appris quelque chose, et que cela vous a servi :)

Coding4Fun

jeudi 26 août 2010

Gestion des Type Enum C#

Bonjour a tous !

De retour de vacances, en forme pour de nouveau épisode de code sur mon Blog ^^. J'espère que pour vous que vos vacances se sont bien passé et que vous avez pu vous reposez et profitez du soleil.

Un petit billet pour faire quelques explication sur les Enum en C#.

Ma question initial était de pouvoir avoir des types défini et comparable en string. Cependant a ma connaissance les Enums n'etaient que comparable avec des int de cette manière :

private enum InputType
{
    Checkbox,
    Hidden,
    File,
    Password,
    Radio,
    Reset,
    Submit,
    Text
}

... InputType.Text == 7 ...

Or, ce que je souhaite c'est de pouvoir afficher le texte de mon Enum (et non la valeur) :

Console.WriteLine("Le champ Text : " + InputType.Text)
// produit : Le champ Text : 7

Pour cela, il faut utiliser les méthodes présentes dans System.Enum : (2 essentiellement)

// Récupération de tous les textes de l'enum en question
var tab = System.Enum.GetNames(typeof(InputType));
// Récupération du texte de l'enum donné
var elm = System.Enum.GetName(typeof(InputType), InputType.Checkbox);

Cependant, une méthode plus courte existe, l'utilisation du .ToString() sur le type donné. Néanmoins, l'intellissence de Visual Studio (2008 - C# 3.5) note que cette méthode est désapprouvée et qu'il faut utiliser System.Enum.ToString() ?!

Ça marche très bien comme cela :

string val = InputType.Text.ToString();

vendredi 9 juillet 2010

Gestion des paramètres culturel MVC Asp.net

Bonjour,

Petite news bien pratique, la gestion de la culture sur un site MVC en Asp.Net.

Dans mon cas, je travail en local (dev) sur mon Poste Windows, en français. Or lorsque je déploie il n'est pas toujours évident de retrouver les paramètre culturel identique a son poste de travail.

Pour cela, il suffit de rajouter ses quelques lignes dans le fichier Global.asax.cs

/// 
/// Begin Request début de requete HTTP sur l'application
/// 
/// /// protected void Application_BeginRequest(object sender, EventArgs e)
{
    HttpCookie cookie = Request.Cookies["CultureInfo"];

    if (cookie != null && cookie.Value != null)
    {
      Thread.CurrentThread.CurrentUICulture = new CultureInfo(cookie.Value);
      Thread.CurrentThread.CurrentCulture = new CultureInfo(cookie.Value);
    }
    else
    {
      Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR");
      Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
    }
}        

mercredi 9 juin 2010

Ne pas mettre a jour une table/entité avec Nhibernate

Bonjour a tous,

Aujourd'hui je me suis confronté a un problème de mise a jour par Nhibernate. Je m'explique, j'ai un traitement qui récupère/parcours plusieurs objets/entités mappées depuis une vue (oracle) bien spécifique (jointures...).

Le souci c'est que je modifie les enregistrements de cette vue pour effectuer un certain nombre de contrôle. Suite a ces tests, j'ai une opération de suppression (delete) ou mise a jour (update). Pour ces deux commandes, je stipule deux choses sur la session :

this.Session.Update(entite);
this.Session.Flush();

Or dans mon cas j'obtiens une erreur sur un update non souhaité du type : 
NHibernate: UPDATE vue_qui_va_bien SET champ1 = :p0 WHERE id= :p1;:p0 = '00000', :p1 = 123
Deux solutions se présente alors pour la gestion des mise a jour des tables et objets.

1° Lecture seule - Readonly sur tout la table


En précisant le terme mutable="false", cela précise à Nhibernate de ne pas mettre a jour cette table (vue). Aucune commande Update ou Delete ne sera effectué ! Nickel c'est ce que je voulais.

http://www.dil.univ-mrs.fr/~massat/docs/hibernate-3.1/reference/fr/html/mapping.html#mapping-declaration-class
     mutable (optionnel, vaut true par défaut) : Spécifie que des instances de la classe sont (ou non) immuables.


2° Lecture seule - Readonly sur un ou plusieurs enregistrements

En précisant le terme update="false" sur le ou les champs en question. Nhibernate ne fera pas de mise a jour si celui ci est modifié.

En esperant que cela vous aide dans vos développements avec Nhiberate !

mardi 20 avril 2010

Clé composite, mapping et class avec Nhibernate

Il vous est peut etre déja arrivé d'essayer de mapper une table qui ne contient aucune clé primaire (ou alors qui est composé). Pour ma part, hier cela m'est arrivé !
C'est ce que je vais essayer de décrire dans les étapes suivantes.

Lors de l'execution et du mapping de NHibernate, logiquement (sans mettre de clé primaire dans votre fichier xml), vous devriez tomber sur ce message :
- “composite-id class must override Equals()”
- “composite-id class must override GetHashCode()”

Pour corriger cette erreur, il faut absoluement avoir une clé primaire. Dans notre cas, elle sera composée (de Contrat_ID et Code_Agn).

Voici notre mapping:

















Notre classe :
public class Allegement
{
    public virtual string Contrat_ID { get; set;}
    public virtual string Lot_Paie { get; set;}
    public virtual string Montant_ALLGT_1 { get; set;}
    public virtual string Code_Agn { get; set; }

    // nécessaire lors des clés composites
    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;

        Allegement a = obj as Allegement;
        if (a == null)
            return false;

        if (this.Contrat_ID == a.Contrat_ID && this.Code_Agn == a.Code_Agn)
            return true;
        else
            return false;
    }

    // necessaire lors des clés composites
    public override int GetHashCode()
    {
        int hash = 666; // ce que l'on veux 
        hash += (null == this.Contrat_ID ? 0 : this.Contrat_ID.GetHashCode());
        hash += (null == this.Code_Agn ? 0 : this.Code_Agn.GetHashCode());

        return hash;
    }
}}

Les élements a retenir de cet exemple sont :
- pas de mapping sans clé primaire
- la redefinition des méthodes "Equals" et "GetHashCode", des classes de bases

Pour plus d'information sur le mapping : http://nhforge.org/doc/nh/en/index.html dans la partie "5. Basic O/R Mapping"

mardi 13 avril 2010

Récupération valeur d'une séquence Oracle avec NHibernate

Bonjour à tous,

Aujourd'hui je vais vous présentez comment récupérer une valeur d'une séquence oracle (SEQ_NAME.NEXTVAL) à l'aide de NHibernate sans écrire la requête SQL. A vrai dire l'information n'est pas facile a dénicher sur le net.

Donc voici les quelques lignes de code qui permettent de récupérer la nouvelle valeur :

NHibernate.Dialect.Oracle10gDialect dial = new NHibernate.Dialect.Oracle10gDialect();
string sqlString = dial.GetSequenceNextValString("SEQ_NAME"); // génère Select SEQ_NAME.NEXVAL FROM DUAL

ISQLQuery sqlQuery = _session.CreateSQLQuery(sqlString);
return sqlQuery.UniqueResult().ToString();

C'est plutôt simple, et donc il est facile d'étendre vos objets pour rendre cette partie un peu plus générique ;)

Bonne journée à tous

mardi 6 avril 2010

Concept Objet : quelques rappels ...

Bonjour,

Aujourd'hui je vous propose un petit billet de "rappel" sur les concepts de la programmation orientée objet (POO). Qui je doit le reconnaitre m'était sorti de la tête.
En effet, je ne faisait que du "procédurale" (en asp.net c# 1.1) ... les concepts de base se sont vite oubliés.
Mais désormais je réfléchi sur les architectures (Asp.Net MVC 3.5) et force est de constater que les concepts obscures (et chiants ?) vu en cours pendant mes études, deviennent des concepts tout à fait géniaux. Dès lors ou l'on comprend réellement leur application, tout parait bien plus "naturel".

Je vais essayer de vous présenter les différentes méthodes que je côtoie actuellement. Cela me permet, d'une part d'une part de mieux appréhender le sujet, et d'autre part de le récupérer sur le blog dans le cas ou j'aurai un trou de mémoire. (ce qui arrive malheureusement)

Mots clés :

- override : notifie que la méthode (ou attribut) est réécrit/redéfini dans la classe fille
- Virtual : permet de réécrire (c'est optionnel) la méthode dans une classe fille grace au mot clé override
- abstract : force la classe fille de réecrire la méthode (override). Attention, nécessite que la classe mère soit noté abstract également.


Exemple :
public abstract class Service< T >     // "T" : Generic - Correspond a un modèle
{
   protected Repository repo;

   public virtual T FindOne(object id)
   {
      return repo.FindOne< T >(id);
   }

   public abstract void Save(T entite);
}

public class Commune_Service : Service< commune >
{
   // obligatoire : ne compile pas si elle n'est pas définie
   public override void Save(Commune entite) 
   {
      throw new NotImplementedException();
   }
}

Visual Studio vous apporte un coup de pouce :

mercredi 17 février 2010

Respect nomenclature MVC

Bonjour,

Un petit billet rapide pour vous méfier des syntaxes sur MVC. En effet, j'ai été confronté a un problème très bête, mais lorsque l'on n'est pas habitué a MVC on peux chercher longtemps l'erreur.

Voici l'erreur :
System.ArgumentException: The parameters dictionary contains a null entry for parameter 'idCategorie' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Cat(Int32)' in 'SiteArticle.UI.Controllers.ArticleController'. To make a parameter optional its type should be either a reference type or a Nullable type.
Nom du paramètre : parameters

Accès :
http://localhost:53809/Article/Cat/3

Code :
public ActionResult Cat(int idCategorie)
{
    IEnumerable< article > IEArticle = this._service.ListArticles(idCategorie);

    if (IEArticle.Count() > 0)
        return View(IEArticle);
    else
        return View("NotFound");
}

En fait, le problème est simpliste... dans votre route (Global.asax) vous avez défini la règle
suivante (enfin MVC de microsoft ?!) :
routes.MapRoute(
    "Default",                                              // Route name
    "{controller}/{action}/{id}",                           // URL with parameters
    new { controller = "Article", action = "Index", id = "" }  // Parameter defaults
);

Depuis ce routage, le nom de la variable est obligatoirement "id" si vos méthodes de vos controllers ne respectent pas cette nomenclature vous aurez le message d'erreur.

C'est tout bete, mais on peux chercher parfois pendant des heures pourquoi on a ce type de probleme !

Enjoy

Mise à jour partielle d'entités NHibernate et MVC

Bonjour,

Suite a des petits problèmes de compréhension de NHibernate et MVC sur la modification des objets, je me permet de mettre un petit billet pour expliquer mes problèmes et pour montrer comment je les aient résolus.

Initialement dans mon controller, j'ai une méthode en POST qui souhaite mettre a jour un article :

// fonctionne si tous les champs du formulaire doivent etre mise a jour or dans mon cas, la date de création/modif
// ne doivent pas etre mis a jour !
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Article articleToEdit) 
{
    if (this._service.EditArticle(articleToEdit))
        return RedirectToAction("Index");
    return View();
}

Cela fonctionne bien, sauf que pour mon article en édition, je n'ai pas rempli de date de création, de ce fait, l'objet "articleToEdit" a comme "01/01/0001" en valeur d'attribut datecreation.

Pour mettre a jour un article, il faut récupéré l'identifiant de l'article et travailler avec ce dernier pour le mettre a jour.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection collection)
{
    Article articleToEdit = this._service.GetArticle(id);
    UpdateModel(articleToEdit);

    if (this._service.EditArticle(articleToEdit))
        return RedirectToAction("Index");
    return View();     
}

En fait, on va tout d'abord récuperer l'article a éditer, et à l'aide de la méthode "UpdateModel" (implémentée par le controller), cela nous permet de mettre a jour notre articleToEdit avec les informations de notre formulaire.
En débuggage on le voit tres bien :

Avant :
Apres :

mercredi 3 février 2010

TP Active Record - Articles/Catégorie [Compil] (Partie 4)

Nous voici dans la 4nd section TP Active Record, ceci est l'explication pas à pas d'un TP de création de site Web permettant de créer des articles et d'en associer des catégories.
Voici la liste des articles disponibles :
Dans cette partie nous allons verifier le fonctionnement du code que vous avons produit dans les parties précédentes.

TP Active Record - Articles/Catégorie [NHibernate] (Partie 3)

Nous voici dans la 3nd section TP Active Record, ceci est l'explication pas à pas d'un TP de création de site Web permettant de créer des articles et d'en associer des catégories.
A ce niveau la nous utiliserons le pattern  " ActiveRecord " de l'API Castle Project utilisant NHibernate. ActiveRecord est un design pattern qui permet de masquer la complexité des interactions avec la base de données en évitant d'écrire du code SQL
Le gros avantage avec ce pattern c'est qu'il permet d'écrire aussi dans une seule et même classe le mapping base de données et la classe/l'objet métier. Je vous invite à lire l'article montrant les différences de fonctionnement entre " ActiveRecord " et un accès classique NHibernate (Mapping_NHibernate_2010-01 ...).

TP Active Record - Articles/Catégorie [Archi] (Partie 2)

Nous voici dans la 2nd section TP Active Record, ceci est l'explication pas à pas d'un TP de création de site Web permettant de créer des articles et d'en associer des catégories.
Nous allons décrire les étapes pour créer une solution depuis Visual Studio 2008 simple et pratique pour la réalisation de notre TP. Je rappel que cette solution n'est pas l'unique solution, mais me convient pour l'instant.

TP Active Record - Articles/Catégorie [Intro] (Partie 1)

Bonjour a tous,

Dans ce 1er TP, nous allons créer un site permettant de gerer des articles associés a des catégories. Un sujet classique, cas d'école, qui nous permettra de voir les différents concepts : NHibernate, MVC 3.5, Castle Active Record, Linq et bien d'autres.
Voici le sommaire que je vous propose :

lundi 1 février 2010

Portage du tutoriel Contact Manager de Entity Framework à NHibernate (et Oracle)

De la même maniere que mon cher collègue Michel, sur son blog (Linq To SQL). Je vais vous présentez comment migrer de Entity Framework à NHibernate + Oracle.

Tout d'abord les informations nécessaires

Création du modèle
Tout de suite, ici il ne s'agit pas de faire du drag'n drop de vos tables avec de beaux object Visual Studio ! Il faut coder lignes par lignes notre modele de persistance.
Tout d'abord supprimez :
  • le fichier "modele" .edmx
  • les références inutiles (System.Data.Entity)
  • le repository : EntityContactManagerRepository.cs

lundi 25 janvier 2010

Exception Oracle 64 bits / 32 Bits

Si vous etes sous un environnement 64bits comme moi et que vous developpez avec visual studio et avec Oracle il vous est peut etre déjà arrivé de voir cette erreur :

La tentative de chargement des bibliothèques du client Oracle a renvoyé BadImageFormatException. Ce problème se produit en mode 64 bits avec les composants du client Oracle 32 bits installés.
Tout simplement, c'est que le client Oracle installé sur votre machine n'est pas de type 64bits et donc de ce fait, l'application s'exécutant en 64bits pose souci !

Pour y remédier, tout simplement : Bouton droit >> Propriétés de votre Application, Onglet "Générer" et choisissez x86


lundi 11 janvier 2010

Création d'un contrainte de type booleen Oracle (Check)

Bonjour,

La petite astuce du jour, et de créer un champs "Booleen" dans Oracle. Or Oracle n'a pas ce type de champs possible lors de la création de table. Il n'existe que en PL/SQL.

Cependant, il existe une méthode simple pour effectuer ce contrôle : UNE CONTRAINTE CHECK.

En voici un exemple :
ALTER TABLE SU.POSTS ADD (
  CONSTRAINT BOOL_POSTISPUBLIC
 CHECK (ispublic=0 OR ispublic=1));

Tout simplement, on rajoute la contraint Check sur la tabel "POSTS" et sur le champs ISPUBLIC pour authoriser uniquement la valeur 0 ou 1.


Bonne journée

vendredi 8 janvier 2010

Ajouter SyntaxHighlighter et les Brushes dans blogger

Pour rappel,

Voici la méthode qui permet d'ajouter la colorisation syntaxique (SyntaxHighlighter) depuis votre blog google (blogger).

1. Editer l'HTML de votre blog
2. Faites éventuellement une sauvegarde
3. Rajouter ces quelques lignes juste après le   pour activer la colorisation :





4. Rajouter les brushes que vous souhaitez inclure a votre blog :






La liste des brushes est disponible : http://alexgorbatchev.com/wiki/SyntaxHighlighter:Brushes


Attention ! Si vous changer de theme, penser a refaire cette manipulation pour ré-activer la colorisation !!!

Ou est asp.net 3.5 sur IIS6 ?

http://blogs.msdn.com/vijaysk/archive/2008/03/20/running-asp-net-3-5-on-iis.aspx

NHibernate et les Séquences Oracle

Bonjour, voici un nouveau billet concernant l'utilisation de NHibernate avec Oracle et .Net.

Le problème rencontré était l'utilisation d'un identifiant unique pour la création de données dans une table. Comme vous le savez peut etre déja, Oracle n'a pas de type "AUTO-INCREMENT"/"IDENTITE" comme Mysql ou SqlServeur. Pour pallier a cette contrainte il "suffit" de créer une SEQUENCE et d'utiliser cette derniere pour prendre de maniere unique l'identifiant de notre table.

Le but de ce billet n'etant pas d'expliquer les Sequence, je vous laisse la lecture de ce site pour la compréhension : http://www.commentcamarche.net/contents/oracle/oracseq.php3

Revenons a nos mouton : NHibernate est-il capable de gérer nativement les identifiants uniques ? C'est effectivement le cas ! Chouette ! Comment vous allez me dire ? C'est pas très compliqué, il suffit de modifier votre fichier de mapping comme ceci :

mardi 5 janvier 2010

Mot Clé [Conditional("DEBUG")] et #if DEBUG

Bonjour,

Voici un nouvel article sur l'utilisation de certain mot clé que je viens de découvrir en C# par hazard.
Il s'agit de [Conditional("DEBUG")] et #if DEBUG

Ses deux mots clés permettent de "cacher" des méthodes ou des portions de code lors de la compilation en "RELEASE". En voici un exemple :

#if DEBUG
MaMethode();
#endif

Dans cette exemple le code contenu entre le #if et #endif sera complètement supprimé en Release

[Conditional("DEBUG")]
public static void MaMethode()
{
Console.WriteLine("Hello");
}

Dans cette exemple, l'appel sera de la main sera uniquement supprimé mais pas la fonction. Dans les 2 cas on arrive au meme résultat.

Pour des soucis de sécurité on peut associer les 2 cf ce blog

Cela peut être utile en travail d'equipe avec un controle de code source exclusif (SourceSafe).