2011-09-22 22 views
11

Tengo un problema en el que cada vez que publico un formulario de regreso a la versión [HttpPost] de la acción de mi controlador, el ModelBinder devuelve un objeto nulo. No puedo entender por qué. Si cambio la firma para usar un FormCollection, en su lugar, puedo ver que se han configurado todas las claves correctas. ¿Alguien me puede ayudar a señalar el problema aquí, porque no puedo detectarlo?ASP.NET MVC Model Binder devuelve el objeto nulo

Éstos son los modelos para trabajar con mis puntos de vista

public class DeviceModel 
{ 
    public int Id { get; set; } 

    [Required] 
    [Display(Name = "Manufacturer")] 
    public int ManufacturerId { get; set; } 

    [Required] 
    [Display(Name = "Model")] 
    [StringLength(20)] 
    public string Model { get; set; } 

    [StringLength(50)] 
    [Display(Name = "Name")] 
    public string Name { get; set; } 

    [StringLength(50)] 
    [Display(Name = "CodeName")] 
    public string CodeName { get; set; } 

    public int? ImageId { get; set; } 
} 

public class DeviceCreateViewModel : DeviceModel 
{ 
    public IEnumerable<SelectListItem> Manufacturers { get; set; } 
} 

que utilizo en mi controlador de este modo:

public ActionResult Create() 
{ 
    DeviceCreateViewModel viewModel = new DeviceCreateViewModel() 
              { 
               Manufacturers = ManufacturerHelper.GetSortedManufacturersDropDownList() 
              }; 

    return View(viewModel); 
} 

[HttpPost] 
public ActionResult Create(DeviceModel model) 
{ 
    // if I check model here it is NULL 
    return View(); 
} 

y la vista se parece a esto:

@model TMDM.Models.DeviceCreateViewModel 

<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) 
    <fieldset> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.ManufacturerId) 
     </div> 
     <div class="editor-field"> 
      @Html.DropDownList("ManufacturerId", Model.Manufacturers) 
      @Html.ValidationMessageFor(model => model.ManufacturerId) 
     </div> 

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

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

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

     <p> 
      <input type="submit" value="Save" class="medium green awesome" /> 
      @Html.ActionLink("Cancel", "Index", "Device", null, new { @class="medium black awesome" }) 
     </p> 
    </fieldset> } 

Respuesta

29

El problema es que hay una colisión de nombre entre la propiedad denominada Model en la clase DeviceModel y la variable llamada model en la acción Create. La colisión del nombre hace que el DefaultModelBinder falle, ya que intenta vincular la propiedad Model a la clase DeviceModel.

Cambie el nombre de la variable en la acción Crear al deviceModel y se enlazará correctamente.

+0

¡Eso funcionó gracias! ¿Pero por qué el modelo de nombre funciona para otro controlador que tengo que acepta datos de HttpPost? – Chris

+0

¿El modelo para esa acción también tiene una propiedad llamada Modelo? La razón por la que falló aquí fue por la colisión del nombre. – counsellorben

+0

OH, lo siento, realmente entendí mal lo que decías antes, pero ahora estoy claro. Gracias por tu ayuda. – Chris

Cuestiones relacionadas