2011-11-05 28 views
14

Tengo dos modelos, que se ven a continuación, y estoy tratando de insertar uno de cada uno en la base de datos desde una vista. He creado un modelo de vista en un intento de hacer esto.MVC3 - Insertar usando ViewModel - Referencia de objeto no establecida en una instancia de un objeto

public class Blog 
{ 
    public int BlogID { get; set; } 
    public string Title { get; set; } 
    public DateTime CreatedOn { get; set; } 

    public virtual User User { get; set; } 
    public virtual ICollection<BlogPost> Posts { get; set; }  
} 

public class BlogPost 
{ 
    public int PostID { get; set; } 
    public string Body { get; set; } 
    public DateTime CreatedOn { get; set; } 

    public int UserID { get; set; } 
    public virtual User User { get; set; } 
} 

public class BlogViewModel 
{ 
    public Blog Blog { get; set; } 
    public BlogPost BlogPost { get; set; } 
} 

Usando el modelo de vista i estoy publicando al controlador crear:

[HttpPost] 
    public ActionResult Create(BlogViewModel blog) 
    { 
     if (ModelState.IsValid) 
     { 
      User user = unit.UserRepository.GetUser(); 
      blog.Blog.User = user; 
      blog.Blog.CreatedOn = DateTime.Now; 

      unit.BlogRepository.Insert(blog.Blog); 
      unit.BlogPostRepository.Insert(blog.BlogPost); 
      unit.Save(); 

      return RedirectToAction("Index"); 
     } 

     return View(blog); 
    } 

Este seguir tirando el error

referencia a objeto no establecida como una instancia de un objeto.

en la línea blog.Blog.User = user.

¿Alguna idea de lo que estoy haciendo mal?

EDITAR he comprobado los datos POST y era todo lo que hay y correcta pero estaba publicando todo como Blog.Title = y BlogPost.Body = por lo que el modelo de vista en el controlador no recibía nada. Si cambio la ActionResult controlador para:

public ActionResult Create(Blog blog, BlogPost post)

entonces todas las obras. Entonces, ¿por qué los datos no se envían en el formato viewmodel? Estoy usando la interacción basada en el modelo de vista explícita entre sus puntos de vista y el controlador

@model Test.Models.BlogViewModel 
@using (Html.BeginForm()) 
{ 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>Blog</legend> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.Blog.Title) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Blog.Title) 
      @Html.ValidationMessageFor(model => model.Blog.Title) 
     </div> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.BlogPost.Body) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.BlogPost.Body) 
      @Html.ValidationMessageFor(model => model.BlogPost.Body) 
     </div> 
     <p> 
      <input type="submit" value="Create" /> 
     </p> 
    </fieldset> 
} 
<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 
+0

Muéstranos el código de la vista – twoflower

+0

Sí, sin ver cómo su vista está utilizando el modelo de vista, no podemos ayudarle. –

+0

He agregado la vista. Muchas gracias. –

Respuesta

35

simplemente cambiar el nombre del argumento de la acción:

public ActionResult Create(BlogViewModel viewModel) 

Hay un conflicto debido a que su argumento de la acción se llama blog y sin embargo, su modelo de vista (BlogViewModel) tiene una propiedad llamada Blog. El problema es que la carpeta de modelo predeterminada ya no sabe qué hacer en esa situación.

Ah, y si necesita absolutamente tener su argumento de acción llamado blog, también podría cambiar el nombre de la propiedad Blog en su modelo de vista.

+0

¡Muchas gracias! –

+0

maaan! ¡Yo tuve el mismo problema! Gracias @Darin Dimitrov –

+0

Wow, no lo hubiera descubierto solo, ¡gracias! – Psddp

4

He corrido en este tipo de situación antes. Esto sucede, cuando los datos que está enviando desde su vista no están en un formato, ese motor de vinculación de modelo predeterminado MVC puede entender o puede mapear a su objeto de modelo de vista. Intente usar "FireBug" y vea cómo se pasan los datos a través de POST. Y luego vea, si esos datos se pueden mapear a la definición de su modelo de vista.

Una cosa más, ¿está utilizando jQuery para pasar los datos o está utilizando la interacción basada en el modelo de vista explícita entre sus puntos de vista y el controlador?

+0

¡Gracias! He actualizado la pregunta para reflejar esto ... –

0

@ Michael Willmott

Aunque este tema es de 6 años de edad, pero me entero de que es útil para un escenario que he tratado recientemente.

En mi vista de MVC, en lugar de usar una ruta completa para los identificadores, utilicé la variable de acceso directo en línea con Razor y eso causó que el modelo de vista de devolución de datos al servidor fuera nulo.Eso fue debido a que el "nombre" y "id" atributos a los elementos HTML no se procesan correctamente como mecanismo de unión MVC espera:

La siguiente es la declaración equivocada:

@{ 
    var b = Model.Blog; // short cut caused problem of postback model binding 
} 

<div class="editor-field"> 
      @Html.EditorFor(model => b.Title) 
      @Html.ValidationMessageFor(model => b.Title) 
     </div> 

La siguiente es la declaración correcta como ruta completa para los identificadores que se necesita:

<div class="editor-field"> 
      @Html.EditorFor(model => model.Blog.Title) 
      @Html.ValidationMessageFor(model => model.Blog.Title) 
     </div> 
Cuestiones relacionadas