RobinVW
RobinVW

Reputation: 23

ASP.NET MVC ViewModel Property is null

I have the following ViewModel:

public class ProjectViewModel
{
    public Project Project { get; set; }
    public Customer Customer { get; set; }
}

The Customer property is only used to link a new Project to the Customer, so I don't include this property in my Create view, which looks like this:

@using (Html.BeginForm()) 
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
    <h4>Project</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.Project.Name, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Project.Name, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Project.Name, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
</div>
}

When I post the form, the following method in my ProjectsController is triggered:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Project,Customer")] ProjectViewModel vm)
{
    var project = Mapper.Map<Project>(vm);
    if (ModelState.IsValid)
    {
        _db.Create(project);
        return RedirectToAction("Index");
    }
    return View(vm);
}

This is where the unexpected behaviour occurs. Now, when I examine the vm property, the Customer property is null.

The question How can I still keep the Customer property filled, while not using it in the view?

Upvotes: 2

Views: 1525

Answers (3)

User123
User123

Reputation: 599

To make sure the Customer property is never null when initializing ProjectViewModel, you could add a constructor to your ProjectViewModel class initializing the Customer property to a new Customer() like so:

public class ProjectViewModel
{
    // Constructor
    public ProjectViewModel()
    {
        Customer = new Customer();
    }

    public Customer Customer { get; set; }
}

Upvotes: 0

Erik Funkenbusch
Erik Funkenbusch

Reputation: 93434

The short answer is that you can't. When data is posted back, the only data that is included is what is in the form on the HTML page.

Your best bet is to either use a session variable or look up the data again in the post handler, or alternatively, serialize the data to hidden fields.

Upvotes: 2

Ingenioushax
Ingenioushax

Reputation: 718

If you want to persist your Customer data, then you need to set all the fields as hidden elements otherwise they will be lost in the redirect.

@Html.HiddenFor(model => model.Customer.Property1) ...etc...

Upvotes: 5

Related Questions