none
Inconveniente al editar modelos: El diccionario de parámetros contiene una entrada NULL RRS feed

  • Pregunta

  • Hola Amigos yo de nuevo :D

    Tengo un inconveniente al tratar de hacer una edición. Antes que nada debo contarles que trabajo con Areas para administrar mejor la aplicacion. El problema lo tengo dentro de una de las Areas llamada "Administrador" .

    El siguiente es el código del controlador, en el cual uso una variable de sesión que ha sido previamente creada y su función es editar los datos de los modelos que obtengo.

      public ActionResult Edit()
            {
                decimal id;
                id = (decimal)Session["Consul"];
                SEDE_UNIVERSIDAD sede_universidad = db.SEDE_UNIVERSIDAD.Single(s => s.IdConsultorio == id);
                ViewData.Model = db.CONSULTORIO.Single(c => c.IdConsultorio == id);
                ViewBag.Universidad = db.UNIVERSIDAD.Single(u => u.IdUniversidad == sede_universidad.IdUniversidad);
                ViewBag.Sede = db.CIUDAD_SEDE.Single(u => u.IdCiudadSede == sede_universidad.IdCiudadSede);
                return View(sede_universidad);
            }
    
             [HttpPost]
            public ActionResult Edit(SEDE_UNIVERSIDAD sede_universidad, CONSULTORIO consultorio)
            {
                if (ModelState.IsValid)
                {
                    db.SEDE_UNIVERSIDAD.Attach(sede_universidad);
                    db.ObjectStateManager.ChangeObjectState(sede_universidad, EntityState.Modified);
                    db.SaveChanges();
    
                    db.CONSULTORIO.Attach(consultorio);
                    db.ObjectStateManager.ChangeObjectState(consultorio, EntityState.Modified);
                    db.SaveChanges();
    
                    return RedirectToAction("Index");
                }
                ViewBag.IdCiudadSede = new SelectList(db.CIUDAD_SEDE, "IdCiudadSede", "Nombre", sede_universidad.IdCiudadSede);
                ViewBag.IdConsultorio = new SelectList(db.CONSULTORIO, "IdConsultorio", "DireccionConsultorio", sede_universidad.IdConsultorio);
                ViewBag.IdUniversidad = new SelectList(db.UNIVERSIDAD, "IdUniversidad", "Nombre", sede_universidad.IdUniversidad);
                return View(sede_universidad);
            }
    

    En siguiente es el código de la vista

    @model RolesMVC3.Models.SEDE_UNIVERSIDAD
    
    @{
        ViewBag.Title = "Edición de consultorios"; 
    }
    
    <h2>EDICIÓN DE CONSULTORIOS</h2>
    
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
    
    @using (Html.BeginForm()) {
        @Html.ValidationSummary(true)
        
        <h2> @ViewBag.Universidad.Nombre - @ViewBag.Sede.Nombre </h2>
        
        <fieldset>
            <legend>MODIFICAR CONSULTORIO</legend>
    
            @Html.HiddenFor(model => model.IdUniversidad)
    
            @Html.HiddenFor(model => model.IdCiudadSede)
             
            @Html.HiddenFor(model => model.IdConsultorio)
    
            <div class="editor-label">
                @Html.LabelFor(model => model.DireccionSede, "Dirección Sede")
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.DireccionSede)
                @Html.ValidationMessageFor(model => model.DireccionSede)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.TelefonoSede, "Teléfono Sede")
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.TelefonoSede)
                @Html.ValidationMessageFor(model => model.TelefonoSede)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.CorreoSede, "Correo Sede")
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.CorreoSede)
                @Html.ValidationMessageFor(model => model.CorreoSede)
            </div>
    
            <fieldset>
            <legend>DATOS ESPECÍFICOS</legend>
            @Html.Partial("_Consultorio", Model.CONSULTORIO)
            </fieldset>
    
            <p>
                <input type="submit" value="Guardar" />
            </p>
        </fieldset>
    }
    
    <div>
        @Html.ActionLink("Ver Listado", "Index")
    </div>
    

    El problema ocurre cuando primo el botón "Guardar", sale el siguiente error :

    El diccionario de parámetros contiene una entrada NULL para el parámetro 'id' del tipo que no acepta valores NULL 'System.Decimal' del método 'System.Web.Mvc.ActionResult Index(System.Decimal)' en 'RolesMVC3.Areas.Administrador.Controllers.ConsultorioController'. Un parámetro opcional debe ser un tipo de referencia, un tipo que acepte valores NULL o debe declararse como parámetro opcional.
    Nombre del parámetro: parameters

    Gracias por su ayuda!


    CADAVID

    viernes, 23 de marzo de 2012 4:07

Respuestas

  • Buenas!

    Vale... bueno, deduzco por donde van los tiros.

    El problema que tienes es que cuando haces el post, el ModelBinder debe enlazar las propiedades del ViewModel con los datos de la request. El problema está en que cuando intenta enlazar la propiedad "id" esta no se encuentra (porque no tienes ningún @EditorFor para la propiedad Id). Entonces intenta asignarle null, pero es un decimal y peta.

    Dos soluciones, una mala y otra la buena :P

    • La mala: En la vista meter un @Html.HiddenFor para el Id. Porque es la mala? Porque estás enviando el Id por POST, si alguien pilla fiddler o lo que sea y modifica la petición te podría poner los Ids que quisiera.
    • La buena: Excluir la propiedad Id del Model Binding. Así el ModelBinder no enlazará esta propiedad (ten presente que te llegará con el valor por defecto, en el caso de decimal un 0)

    Para ello, debes editar tu controlador y decorar el parámetro de la acción con [Bind], algo asi:

    [HttpPost]
    public ActionResult Edit([Bind(Exclude="Id")] SEDE_UNIVERSIDAD sede_universidad, [Bind(Exclude="Id")] CONSULTORIO consultorio)
    {
       //...
    }

    Si no quieres modificar la acción y sabes que NUNCA el Id debe enlazarse puedes aplicar [Bind(Exclude="Id")] al propio ViewModel.

    Un saludo!


    Eduard Tomàs Blog: http://geeks.ms/blogs/etomas -- Twitter: eiximenis

    • Marcado como respuesta CADAVID viernes, 23 de marzo de 2012 15:22
    viernes, 23 de marzo de 2012 7:30