14 Stimmen

MVC3 - Einfügen mit ViewModel - Objektreferenz nicht auf eine Instanz eines Objekts festgelegt

Ich habe zwei Modelle, siehe unten, und versuche, eine von jedem in die Datenbank von einer Ansicht einfügen. Ich habe eine Ansicht Modell in einem Versuch, dies zu tun erstellt.

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

Mit der Ansicht Modell ich bin Posting an den Controller erstellen:

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

Dies führt immer wieder zu der Fehlermeldung

Objektreferenz nicht auf eine Instanz eines Objekts gesetzt.

auf der Linie blog.Blog.User = user .

Irgendwelche Ideen, was ich falsch mache?

EDITAR Ich habe die POST-Daten überprüft und sie waren alle vorhanden und korrekt, aber es wurde alles als Blog.Title = y BlogPost.Body = also empfing das Viewmodel im Controller nichts. Wenn ich den Controller actionresult zu ändern:

public ActionResult Create(Blog blog, BlogPost post)

Dann funktioniert alles. Warum werden die Daten dann nicht im Viewmodel-Format gesendet? Ich verwende explizite Viewmodell-basierte Interaktion zwischen Ihren Ansichten und 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>

35voto

Darin Dimitrov Punkte 990883

Benennen Sie einfach Ihr Aktionsargument um:

public ActionResult Create(BlogViewModel viewModel)

Es gibt einen Konflikt, weil Ihr Aktionsargument heißt blog und dennoch Ihr Ansichtsmodell ( BlogViewModel ) hat eine Eigenschaft namens Blog . Das Problem ist, dass der Standardmodellbinder nicht mehr weiß, was er in einer solchen Situation tun soll.

Ach ja, und wenn Sie Ihr Aktionsargument unbedingt haben müssen blog dann könnten Sie auch die Blog Eigenschaft auf Ihrem Ansichtsmodell.

4voto

Pawan Mishra Punkte 7164

Ich bin schon öfter in solchen Situationen gewesen. Dies geschieht, wenn die Daten, die Sie von Ihrer Ansicht senden nicht in einem Format, das MVC-Standard-Modell-Bindungs-Engine verstehen kann oder kann Ihre Ansicht-Modell-Objekt zuordnen. Versuchen Sie es mit "FireBug" und sehen Sie, wie die Daten per POST übergeben werden. Und dann sehen Sie, ob diese Daten auf die Definition Ihres View-Modells abgebildet werden können.

Eine weitere Sache, sind Sie mit jQuery, um die Daten zu übergeben oder Sie verwenden explizite Ansicht Modell basierte Interaktion zwischen Ihren Ansichten und Controller?

0voto

Thomas.Benz Punkte 7871

@Michael Willmott

Dieses Thema ist zwar schon 6 Jahre alt, aber ich finde es nützlich für ein Szenario, mit dem ich kürzlich zu tun hatte.

In meiner MVC-Ansicht, statt mit einem vollständigen Pfad für Bezeichner, ich verwendet Inline-Kurzschluss-Variable mit Razor und das verursacht die Postback-Ansicht-Modell auf Server war null. Das war, weil die "Name" und "id" Attribute für HTML-Elemente nicht korrekt gerendert wurden, wie MVC Bindungsmechanismus erwartet:

Die folgende Erklärung ist falsch:

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

Die folgende Erklärung ist korrekt, da der vollständige Pfad für die Bezeichner benötigt wird:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X