none
Problema con tryUpdateModel RRS feed

  • Pregunta

  • Hola, estoy teniendo problemas con esta función.

    Mi problema es el siguiente:

    Estoy implementando la típica funcionalidad de cambiar una contraseña, recojo los datos de la vista y tras las comprobaciones pertinentes (contraseña_nueva = contraeña_antigua y los dos campos de contraseña iguales) le asigno la nueva contraseña al modelo pero al hacer la llamada al tryUpdateModel me he fijado en la depuración que esta llamada vuelve a coger el valor antiguo de la contraseña y lo actualiza con ese valor...

    Alguien a que es debido esto.

    Gracias de antemano.

    1 saludo!!

    jueves, 1 de septiembre de 2011 11:27

Respuestas

  • Buenas!

    A ver... te cuento lo que te está pasando. :)

    Cuando haces el TryUpdateModel(miCliente), ASP.NET MVC te va a bindear las propiedades del modelo, con aquellas que se hayan enviado y que coincidan por nombre.

    En tu caso tienes que tu modelo (la clase Cliente) tiene una propiedad llamada Password. Y por un lado le estás mandando 3 valores a ASP.NET MVC (los tres <input> que tienes):

    • Password
    • Pwd1
    • Pwd2

    Por lo tanto, cuando haces el TryUpdateModel, ASP.NET MVC mira tu clase cliente, y encuentra una propiedad llamada Password y le asigna... el valor del <input name="Password">. Y por eso te machaca te sale con la contraseña anterior... porque precisamente este campo contiene la constraseña anterior!

    Haz una cosa, si quieres usar TryUpdateModel, modifica los name de los <input> de forma que el name del <input> que contenga el password nuevo se llame Password (igual que la propiedad del modelo). P.ej. puedes usar:

    <input name="oldpass"> para la password actual

    <input name="Password"> para el nuevo password

    <input name="Password2"> para el nuevo password (repeticion).

    Modificas el código del controlador para hacer:

                   if (miCliente.Password != collection["oldpass"])
                    {
                        ViewBag.informacion = "La contraseña introducida no es correcta.";
                        return View(miCliente);
                    }
                    else if (collection["Password"] != collection["Password2"])
                    {
                        ViewBag.informacion = "Las dos contraseñas no coinciden.";
                        return View(miCliente);
                    }
    
    

    Y luego ya puedes llamar a TryUpdateModel y te cojerá el valor del <input> llamado Password (que ahora es el nuevo password) y te lo asignará a la propiedad Password de tu modelo.

    Un saludo!

    PD: Has considerado en usar DataAnnotations en la clase Cliente en lugar de poner los ifs() en el controlador?


    Eduard Tomàs Blog: http://geeks.ms/blogs/etomas -- Twitter: eiximenis
    viernes, 2 de septiembre de 2011 6:38

Todas las respuestas

  • Hola.

    Necesitaría ver el código para poder orientarte mejor.

    De todas formas, prueba a seguir las indicaciones de este artículo http://msmvps.com/blogs/shahed/archive/2009/05/14/asp-net-mvc-tips-form-post-tryupdatemodel-unit-test-moq.aspx


    "En los momentos de crisis, sólo la imaginación es más importante que el conocimiento" Blog en Geeks
    jueves, 1 de septiembre de 2011 13:01
  • Mi código es este:

    //Vista:

     

    <div class="editor-label">
                @Html.LabelFor(model => model.Password)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Password)
                @Html.ValidationMessageFor(model => model.Password)
            </div>

            <div class="editor-label">
                @Html.Label("Nuevo Password")
            </div>
            <div class="editor-field">
                @Html.Editor("Pwd1")           
            </div>

            <div class="editor-label">
                @Html.Label("Reescribir nuevo Password")
            </div>
            <div class="editor-field">
                @Html.Editor("Pwd2")           
            </div>
            <h2>@ViewBag.Informacion</h2>
            <p>       
                <input type="submit" value="Cambiar" />
            </p>

     

    //Controlador

     

    Cliente miCliente = videoclubDB.Cliente.FirstOrDefault(d => d.id_Socio == id);

                    if (miCliente.Password != collection["Password"])
                    {
                        ViewBag.informacion = "La contraseña introducida no es correcta.";
                        return View(miCliente);
                    }
                    else if (collection["pwd1"] != collection["pwd2"])
                    {
                        ViewBag.informacion = "Las dos contraseñas no coinciden.";
                        return View(miCliente);
                    }
                    else
                    {
                        miCliente.Password = collection["pwd1"];     //Al hacer esto, en el objeto cliente se modifica el campo Password
                       
                        if (TryUpdateModel(miCliente))                  //Pero n esta llamada al recuperar el cliente vuelve a salir con la contraseña anterior
                        {
                            videoclubDB.SaveChanges();
                            return RedirectToAction("Index", miCliente);
                        }
                        else
                        {
                            ViewBag.informacion = "Error";
                            return View(miCliente);                       
                        }
                    }              

    jueves, 1 de septiembre de 2011 14:53
  • Buenas!

    A ver... te cuento lo que te está pasando. :)

    Cuando haces el TryUpdateModel(miCliente), ASP.NET MVC te va a bindear las propiedades del modelo, con aquellas que se hayan enviado y que coincidan por nombre.

    En tu caso tienes que tu modelo (la clase Cliente) tiene una propiedad llamada Password. Y por un lado le estás mandando 3 valores a ASP.NET MVC (los tres <input> que tienes):

    • Password
    • Pwd1
    • Pwd2

    Por lo tanto, cuando haces el TryUpdateModel, ASP.NET MVC mira tu clase cliente, y encuentra una propiedad llamada Password y le asigna... el valor del <input name="Password">. Y por eso te machaca te sale con la contraseña anterior... porque precisamente este campo contiene la constraseña anterior!

    Haz una cosa, si quieres usar TryUpdateModel, modifica los name de los <input> de forma que el name del <input> que contenga el password nuevo se llame Password (igual que la propiedad del modelo). P.ej. puedes usar:

    <input name="oldpass"> para la password actual

    <input name="Password"> para el nuevo password

    <input name="Password2"> para el nuevo password (repeticion).

    Modificas el código del controlador para hacer:

                   if (miCliente.Password != collection["oldpass"])
                    {
                        ViewBag.informacion = "La contraseña introducida no es correcta.";
                        return View(miCliente);
                    }
                    else if (collection["Password"] != collection["Password2"])
                    {
                        ViewBag.informacion = "Las dos contraseñas no coinciden.";
                        return View(miCliente);
                    }
    
    

    Y luego ya puedes llamar a TryUpdateModel y te cojerá el valor del <input> llamado Password (que ahora es el nuevo password) y te lo asignará a la propiedad Password de tu modelo.

    Un saludo!

    PD: Has considerado en usar DataAnnotations en la clase Cliente en lugar de poner los ifs() en el controlador?


    Eduard Tomàs Blog: http://geeks.ms/blogs/etomas -- Twitter: eiximenis
    viernes, 2 de septiembre de 2011 6:38
  • Buf Eduard muchisimas gracias ultimamente me estas salvando eh? :).... Lo de las DataAnnotations si que tengo implementadas pero solamente lo tengo en los campos que contiene el modelo. En este caso tambien podria hacerlo para las dos contraseñas nuevas??

     

    Repito Muchisimas gracias.

    viernes, 2 de septiembre de 2011 9:36