Reputation: 7818
I've a problem with ViewModel posting back to a controller, but the ViewModel not being mapped correctly from the View to the Controller.
TopicId and Content should contain values, however, when posted back, they do not:
VS Debug:
ViewModels:
public class PostViewModel
{
public int PostId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Author { get; set; }
public DateTime DateOfTopic { get; set; }
}
public class ReplyViewModel
{
public int TopicId { get; set; }
public string Content { get; set; }
}
public class PostListAndReplyVM
{
public List<PostViewModel> PostViewModel { get; set; }
public ReplyViewModel ReplyViewModel { get; set; }
}
View:
@model centreforum.Models.PostListAndReplyVM
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>Post</legend>
@Html.HiddenFor(model => model.ReplyViewModel.TopicId)
<div class="editor-label">
@Html.LabelFor(model => model.ReplyViewModel.Content)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ReplyViewModel.Content)
@Html.ValidationMessageFor(model => model.ReplyViewModel.Content)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
Generated HTML:
<form action="/Post/List/7/" method="post"><input name="__RequestVerificationToken" type="hidden" value="xxxxxxxxxxxxx" /> <fieldset>
<legend>Post</legend>
<input data-val="true" data-val-number="The field TopicId must be a number." data-val-required="The TopicId field is required." id="ReplyViewModel_TopicId" name="ReplyViewModel.TopicId" type="hidden" value="7" />
<div class="editor-label">
<label for="ReplyViewModel_Content">Content</label>
</div>
<div class="editor-field">
<input class="text-box single-line" id="ReplyViewModel_Content" name="ReplyViewModel.Content" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="ReplyViewModel.Content" data-valmsg-replace="true"></span>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
</form>
As you can see from the generated HTML, the TopicId definitely has a value: value="7"
Can anyone see where the problem is between the form post, and the controller, which is expecting the ReplyViewModel?
Thank you,
Mark
Upvotes: 0
Views: 8682
Reputation: 25221
The problem is the fact that your view is typed to PostListAndReplyVM
- so it creates names such as ReplyViewModel.Content
- but, because your controller action expects a ReplyViewModel
, these fields can't be bound (i.e. there is no such thing as ReplyViewModel.ReplyViewModel.Content
).
Change your controller action:
public ActionResult List(PostListAndReplyVM reply)
Alternatively - if that's your whole view - just type it to ReplyViewModel
instead (and update your HtmlHelper expressions accordingly).
Upvotes: 3
Reputation: 1038710
Your input field names are prefixed with ReplyViewModel
(because of the model => model.ReplyViewModel.*
lambda), so you need to indicate this information to the model binder:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult List([Bind(Prefix = "ReplyViewModel")] ReplyViewModel model)
{
...
}
Alternatively have your List action take the PostListAndReplyVM model:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult List(PostListAndReplyVM model)
{
// obviously only model.ReplyViewModel will be bound here because
// those are the only input fields in your form
...
}
Upvotes: 3
Reputation: 2284
Its null because you bound it to another model
In view
@model centreforum.Models.PostListAndReplyVM
In Action ReplyViewModel
try to bind like
public ActionResult SomeAction(PostListAndReplyVM model)
{
}
Upvotes: 2