2011-11-05 18 views
14

Ho due modelli, visti di seguito, e sto cercando di inserire uno di ciascuno nel database da una vista. Ho creato un modello di vista nel tentativo di farlo.MVC3 - Inserisci utilizzando ViewModel - Riferimento oggetto non impostato su un'istanza di un oggetto

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; } 
} 

Utilizzando il modello di vista sto inviando al controllore creare:

[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); 
    } 

Questa continuare a lanciare l'errore

riferimento oggetto non impostato a un'istanza di un oggetto.

sulla linea blog.Blog.User = user.

Qualche idea su cosa sto facendo male?

EDIT Ho controllato i dati POST ed era tutto lì e corretti ma era tutto come distacco Blog.Title = e BlogPost.Body = così il ViewModel nel controller non riceveva nulla. Se cambio l'ActionResult controller per:

public ActionResult Create(Blog blog, BlogPost post)

allora tutte le opere. Quindi, perché i dati non vengono inviati nel formato viewmodel? Sto usando l'interazione basata su modello di vista esplicita tra le viste e il controller

@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

ci mostrano il codice della vista – twoflower

+0

Sì, senza vedere come il vostro punto di vista è usando il ViewModel, non possiamo aiutarti. –

+0

Ho aggiunto la vista. Grazie mille. –

risposta

35

sufficiente rinominare il tuo argomento dell'azione:

public ActionResult Create(BlogViewModel viewModel) 

Esiste un conflitto perché il vostro argomento dell'azione si chiama blog eppure il vostro modello di visualizzazione (BlogViewModel) ha una proprietà chiamata Blog. Il problema è che il raccoglitore modello predefinito non sa più cosa fare in tale situazione.

Oh e se hai assolutamente bisogno di avere il tuo argomento di azione chiamato blog allora potresti anche rinominare la proprietà Blog sul tuo modello di vista.

+0

Grazie mille! –

+0

maaan! Ho avuto lo stesso problema! Grazie @Darin Dimitrov –

+0

Wow, non l'avrei capito da solo, grazie! – Psddp

4

Ho già eseguito in questo tipo di situazione. Ciò accade quando i dati inviati dalla vista non sono in un formato, che il motore di associazione modello predefinito MVC può comprendere o può mappare l'oggetto del modello di visualizzazione. Prova a usare "FireBug" e vedi come i dati vengono passati tramite POST. E poi vedi, se questi dati possono essere mappati alla definizione del tuo modello di vista.

Un'ultima cosa, stai usando jQuery per passare i dati o stai usando l'interazione basata su modello di vista esplicita tra le tue viste e il controller?

+0

Grazie! Ho aggiornato la domanda per riflettere questo ... –

0

@ Michael Willmott

Anche se questo argomento è di 6 anni, ma scopro utile per uno scenario mi sono occupato di recente.

Nella mia vista MVC, invece di utilizzare un percorso completo per gli identificatori, ho utilizzato la variabile di taglio inline con Razor e questo ha causato il nullamento del modello di visualizzazione del postback sul server.Questo perché il "nome" e "id" attributi per gli elementi HTML non sono stati resi correttamente come MVC meccanismo di associazione si aspetta:

Quello che segue è la dichiarazione sbagliata:

@{ 
    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> 

Quello che segue è corretta dichiarazione percorso completo per gli identificatori è necessario:

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