none
FormView ne trouve pas les nouvelles valeurs RRS feed

  • Question

  • Bonjour tout le monde,

    La première version de ma page client était basée sur des TextBox qui étaient initialisées dans le Page_Load par une procédure ADO, puis exploitées depuis un bouton de mise à jour par une autre procédure ADO. Je me rappelle un client qui aurait appelé ça la "méthode marteau-burin".

    ça marchait très bien, mais j'ai voulu faire quelque chose de plus propre pour prendre en charge le cas où on n'a pas de mise à jour à faire, pour juste afficher les informations. J'ai donc créé un FormView, et implémenté le ItemTemplate qui affiche, et le EditItemTemplate qui permet de faire de la saisie, accessoirement j'ai copié le EditItemTemplate sur InsertItemTemplate.

    Je commence à me dire que c'était moyennement une bonne idée. Cette fois pour l'affichage ça va très bien, mais il n'y a plus moyen de faire de mise à jour. Je m'intéresse particulièrement à un champ pour les tests, histoire de recopier ce qui marchera sur les autres champs. J'ai renommé son TextBox, pour qu'entre les deux Template il ne porte pas le même nom.

    J'ai essayé toutes sortes de finesses sur la façon de passer les paramètres à la requête, j'ai vu d'ailleurs que je suis loin d'être le seul à me poser cette question (je vise surtout MySql), et pour finir j'ai remis une procédure ADO dans le code du lien de validation, et c'est là que je me suis aperçu que les TextBox qui sont dans le EditItemTemplate continuent de renvoyer l'ancienne valeur, alors même que l'interface utilisateur, toujours à l'écran, permet de vérifier qu'elle n'est plus d'actualité.

    Il y a même plus spectaculaire, je crois que c'est l'événement Updated de la source de données qui a dans ses paramètres OldValues et NewValues, eh bien les deux sont égales. Encore là, au niveau de la source de données c'est normal puisque la mise à jour n'a pas été faite, mais au niveau du FormView et de ses contrôles je m'attendrais quand même à pouvoir retrouver ce qui a été saisi. Mais J'ai parcouru les paramètres de plusieurs procédures événementielles avec l'intellisense dans pas mal de sens, en vain. Peut-être n'ai-je pas encore tapé à la bonne porte ?

    Pour d'autres raison, Visual Studio 2005 a été réinstallé récemment, ainsi que MySql, et SQL Express est en attente de restauration de WMI.

    Mon interface est certes plus belle qu'avant, l'ennui est qu'elle ne fonctionne plus.

    Quelqu'un aurait-il une approche à conseiller ?



    • Modifié Gloops mardi 4 février 2014 11:15
    mardi 4 février 2014 11:12

Réponses

Toutes les réponses

  • Bonjour Gloops

    Qu'est que vous utilisez comme source de données?
    Pour la mise à jour vous utilisez un OleDbDataAdaopter?
    Pour nous faciliter  le travail, pouvez-vous nous faire un petit schéma avec les évènements (Du page, et du FormView) pour mieux voir d'où peut venir le problème?

    Merci!
    Cordialement,


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    mercredi 5 février 2014 08:52
  • Bonjour,
    J'ai essayé cette procédure :

        protected void lnkValidate_Click(object sender, EventArgs e)
        {
            string strSQL = "UPDATE dbo_client SET Title=?Title, FirstName=?FirstName, " +
                    "LastName=?LastName, SurName=?SurName, Comment=?Comment, " +
                    "Address2=?Address2, Address3=?Address3, Address4=?Address4, Address5=?Address5, " +
                    "ZipCode=?ZipCode, Town=?Town, id_pays=?IdPays " +
                    "WHERE PKID=?PKID AND NumAdr=0";
    
            using (MySqlConnection cnx = new MySqlConnection(TrIP.cs("VentesConnectionString")))
            {
                cnx.Open();
                using (MySqlCommand cmd = new MySqlCommand(strSQL, cnx))
                {
    
                    cmd.Parameters.Add(new MySqlParameter("Title", MySqlDbType.String, 10, ParameterDirection.Input, false, 0, 0, "Title", System.Data.DataRowVersion.Current, ((DropDownList)FormView1.FindControl("dnlSalutation")).SelectedValue));
                    cmd.Parameters.Add(new MySqlParameter("FirstName", MySqlDbType.String, 50, ParameterDirection.Input, false, 0, 0, "FirstName", System.Data.DataRowVersion.Current, ((TextBox)FormView1.FindControl("txbEditFirstName")).Text));
                    cmd.Parameters.Add(new MySqlParameter("LastName", MySqlDbType.String, 50, ParameterDirection.Input, false, 0, 0, "LastName", System.Data.DataRowVersion.Current, ((TextBox)FormView1.FindControl("txbLastName")).Text));
                    cmd.Parameters.Add(new MySqlParameter("SurName", MySqlDbType.String, 50, ParameterDirection.Input, false, 0, 0, "SurName", System.Data.DataRowVersion.Current, ((TextBox)FormView1.FindControl("txbSurName")).Text));
                    cmd.Parameters.Add(new MySqlParameter("Comment", MySqlDbType.String, 50, ParameterDirection.Input, false, 0, 0, "Comment", System.Data.DataRowVersion.Current, ((TextBox)FormView1.FindControl("txbComment")).Text));
                    cmd.Parameters.Add(new MySqlParameter("Address2", MySqlDbType.String, 100, ParameterDirection.Input, false, 0, 0, "Address2", System.Data.DataRowVersion.Current, ((TextBox)FormView1.FindControl("txbAddress2")).Text));
                    cmd.Parameters.Add(new MySqlParameter("Address3", MySqlDbType.String, 100, ParameterDirection.Input, false, 0, 0, "Address3", System.Data.DataRowVersion.Current, ((TextBox)FormView1.FindControl("txbAddress3")).Text));
                    cmd.Parameters.Add(new MySqlParameter("Address4", MySqlDbType.String, 100, ParameterDirection.Input, false, 0, 0, "Address4", System.Data.DataRowVersion.Current, ((TextBox)FormView1.FindControl("txbAddress4")).Text));
                    cmd.Parameters.Add(new MySqlParameter("Address5", MySqlDbType.String, 100, ParameterDirection.Input, false, 0, 0, "Address5", System.Data.DataRowVersion.Current, ((TextBox)FormView1.FindControl("txbAddress5")).Text));
                    cmd.Parameters.Add(new MySqlParameter("ZipCode", MySqlDbType.String, 10, ParameterDirection.Input, false, 0, 0, "ZipCode", System.Data.DataRowVersion.Current, ((TextBox)FormView1.FindControl("txbZipCode")).Text));
                    cmd.Parameters.Add(new MySqlParameter("Town", MySqlDbType.String, 100, ParameterDirection.Input, false, 0, 0, "Town", System.Data.DataRowVersion.Current, ((TextBox)FormView1.FindControl("txbTown")).Text));
                    cmd.Parameters.Add(new MySqlParameter("IdPays", MySqlDbType.String, 100, ParameterDirection.Input, false, 0, 0, "id_pays", System.Data.DataRowVersion.Current, ((DropDownList)FormView1.FindControl("dnlCountry")).SelectedValue));
                    cmd.Parameters.Add(new MySqlParameter("PKID", MySqlDbType.String, 100, ParameterDirection.Input, false, 0, 0, "PKID", System.Data.DataRowVersion.Current, ((TextBox)FormView1.FindControl("txbPKID")).Text));
                    cmd.ExecuteNonQuery();
                }
                cnx.Close();
            }
        }

    Et dans les paramètres je me suis aperçu qu'il y avait les anciennes valeurs.

    Si je mets une autre valeur, en dur, à la place du paramètre, elle passe bien dans la table et je la vois en revenant en mode ReadOnly.

    En relisant je vois que j'aurais pu me contenter de 2 comme taille maximale pour l'id_pays plutôt que 100 mis par copier-coller de la ligne du dessus, mais je n'attends pas de miracle de cette correction.

    Avant ça j'ai exploré, avec l'arborescence qui apparaît en plaçant la souris dessus en mode débogage, les arguments des événements suivants :
        protected void dsClient_Updating(object sender, SqlDataSourceCommandEventArgs e)
        protected void dsClient_Updated(object sender, SqlDataSourceStatusEventArgs e)
        protected void txbFirstName_TextChanged(object sender, EventArgs e)
        protected void txbFirstName_DataBinding(object sender, EventArgs e)

    en fait TextChanged non, je n'ai pas exploré les arguments, puisque l'événement ne s'est pas déclenché.


    Quelques extraits de la page. J'ai essayé avec des UpdateParameters, sans, en n'y mettant que la clef, en mettant aussi les champs à modifier, en y mettant des ControlParameters, en y mettant des Parameters simples ...
    Une fois écrite la procédure ci-dessus et effectué les constatations indiquées je me doute que le problème n'est pas là. J'ai laissé des procédures événementielles du FormView dans lesquelles j'ai un peu tâtonné, mais il n'y a plus rien dedans. Je n'ai mis que la balise englobante du FormView pour voir ses propriétés. Dedans il y a un ItemTemplate, un EditItemTemplate, et un InsertItemTemplate. Les deux derniers diffèrent par le nom du TextBox associé au champ sur lequel j'ai fait des tests.
    Dans le ItemTemplate le contenu est de la forme Text='<%# Eval("FirstName") %>', dans les deux autres nous avons Text='<%# Bind("FirstName") %>'.

        <asp:SqlDataSource ID="dsClient" runat="server" ConnectionString="<%$ ConnectionStrings:VentesConnectionString %>"
            ProviderName="<%$ ConnectionStrings:VentesConnectionString.ProviderName %>"
            SelectCommand="SELECT * FROM `dbo_client` WHERE (`PKID` = ?PKID)"
            UpdateCommand="UPDATE dbo_client SET FirstName=?FirstName, Address3='' WHERE (PKID=?PKID)" OnUpdating="dsClient_Updating" OnUpdated="dsClient_Updated"  >
            <SelectParameters>
                <asp:ControlParameter ControlID="lblPkId" Name="PKID" PropertyName="Text" Type="String" />
            </SelectParameters>
        </asp:SqlDataSource>
    
        <asp:FormView ID="FormView1" DataKeyNames="PKID" runat="server" DataSourceID="dsClient" DefaultMode="ReadOnly" OnDataBound="FormView1_DataBound" OnItemUpdated="FormView1_ItemUpdated" OnItemUpdating="FormView1_ItemUpdating">
        </asp:FormView>





    • Modifié Gloops mercredi 5 février 2014 11:34
    mercredi 5 février 2014 11:21
  • Je dirais que la requête SELECT ID="dsClient"  est exécuté avant de faire l'update. Evidement les valeurs saisies par l'utilisateur sont perdus.

    Voir aussi ce thread, c'est bien votre cas?


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    • Marqué comme réponse Gloops mercredi 5 février 2014 12:51
    mercredi 5 février 2014 12:38
  • Effectivement, c'est bien dans cette page que je lis le PKID, et comme la requête l'utilise comme clef, je fais un DataBind juste après l'avoir renseigné.

    Dans d'autres pages je n'ai pas eu ce problème car je renvoie à cette page si la variable n'est pas renseignée, mais là, forcément, non.

    C'est vrai que j'aurais dû penser à mettre un point d'arrêt dans le Page_Load, pour être alerté d'un rechargement.

    C'est bien dû au fonctionnement du FormView, de recharger la page avant la commande Update, n'est-ce pas ?

    Bon, du coup maintenant que je comprends ce qui se passe, je peux corriger.

    Je m'en suis sorti en mettant ceci dans le Page_Load, ce qui fait que la clef est renseignée au chargement et que du coup il n'y a plus besoin de Databind explicite :

                if (HttpContext.Current.Session["PKID"] == null)
                {
                    Andri.Web.MySqlMembershipProvider mp = new Andri.Web.MySqlMembershipProvider();
                    strPKID = mp.GetUserKey(strUserName, strAppName, TrIP.cs("ApplicationServices"));
                    mp = null;
                    HttpContext.Current.Session["PKID"] = strPKID;
                    Response.Redirect("Client.aspx", true);
                }
                else
                {
                    strPKID = HttpContext.Current.Session["PKID"].ToString();
                }
                lblPkId.Text = strPKID;

    Peut-être que j'aurais intérêt à réfléchir un peu à une optimisation des chaînages ...

    Merci de m'avoir trouvé si vite l'explication.


    • Modifié Gloops mercredi 5 février 2014 13:09
    mercredi 5 février 2014 12:50