简体   繁体   中英

ASP.Net MVC Postback from View to Controller shows null values

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: ss

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

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

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 (ie 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).

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)

    {
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM