【问题标题】:View model parameter is null in HttpPost action methodHttpPost 操作方法中的视图模型参数为空
【发布时间】:2016-12-25 12:01:56
【问题描述】:

我将我的 viewModel 从 View1 的 HttpPost 重定向到 View2 的 HttpGet。 这没有问题。 在那里,用户必须接受条款和协议。 这应该在 viewModel 中更改为 true(在它为 false 之前)。 然后重定向到view2的HttpPost。

出了点问题。 View2 的 HttpPost ActionResult 接收到所有参数为 NULL 的视图模型(在它们被填充之前)

我该如何解决这个问题?

这是 View2 的 HttpGet ActionResult:

public ActionResult Verify(QuestionViewModel viewModel)
{
    //Anrede in Viewbag
    if (viewModelVeri.Per_Salutation == 2)
    {
        ViewBag.Per_Salutation = "Frau";
    }
    else
    {
        ViewBag.Per_Salutation = "Herr";
    }

    int? per_region_id = viewModelVeri.Per_Region;
    int per_region_id_nullable = Convert.ToInt32(per_region_id);

    Region region = _repository.GetRegionById(per_region_id_nullable);

    QuestionViewModel viewModel2 = new QuestionViewModel()
    {
        Reg_Name = region.Reg_Name
    };

    //Regionsname in Viewbag
    ViewBag.Reg_Name = viewModel2.Reg_Name; 

    return View(viewModel);
}

这是 View2 的 HttpPost ActionResult:

[HttpPost]
public ActionResult Verify(QuestionViewModel viewModel, string tbButton)
{
    //here the ViewModel-Parameters are already NULL

我的观点:

<div class="panel-body">

@using (Html.BeginForm("Verify", "QuestionForm", FormMethod.Post, new { id = "verifyform" }))
{
@Html.AntiForgeryToken()
    <div class="ctrl-row">
       <div class="form-group">
           <div class="container-fluid">
                 @Html.LabelFor(model => model.Per_Salutation, new { @class = "control-label col-sm-1" })
                 <div class="col-sm-3">
                     @ViewBag.Per_Salutation
                  </div>
            </div>
        </div>
    </div>

    <div class="ctrl-row">
        <div class="form-group">
            <div class="container-fluid">
                @Html.LabelFor(model => model.Per_Name_Last, new { @class = "control-label col-sm-1" })
                <div class="col-sm-3">
                    @Html.DisplayFor(model => model.Per_Name_Last, new { @class = "control-label col-sm-1 non-zero-num" })
                </div>
                @Html.LabelFor(model => model.Per_Name_First, new { @class = "control-label col-sm-1" })
                <div class="col-sm-3">
                    @Html.DisplayFor(model => model.Per_Name_First, new { @class = "control-label col-sm-1 non-zero-num" })
                </div>
            </div>
        </div>
    </div

    <div class="ctrl-row">
        <div class="form-group">
            <div class="container-fluid">
                @Html.LabelFor(model => model.Per_EMail, new { @class = "control-label col-sm-1" })
                <div class="col-sm-8">
                    @Html.DisplayFor(model => model.Per_EMail, new { @class = "control-label col-sm-1 non-zero-num" })
                </div>
            </div>
        </div>
    </div>

    <div class="checkbox">
        <input type="checkbox" id="NutzungsbedingungenAngenommen " />
        <label for="NutzungsbedingungenAngenommen ">
Ich erkläre mich mit den Nutzungsbedingungen einverstanden.
        </label>
    </div>

    <button class="btn btn-default" type="submit" name="tbButton" value="questsend">Senden</button>
}

<script>
    $(document).ready(function () {
        $(".non-zero-num").val($(this).val() == 0 ? ' ' : $(this).val());
    })

    $('#verifyform').on('click', '[value="questsend"]', function () {
        if ($('#agree').is(':checked')) {
            return true;
        }
        else {               
            return false;
        }
    });

</script>

编辑

这是我的 QuestionViewModel

public class QuestionViewModel
{
    //Other Properties

    [Required(ErrorMessage = "Bitte die Nutzungsbedingungen annehmen!")]
    public bool NutzungsbedingungenAngenommen { get; set; }
}

我的 View1 的 HttpPost 控制器:

[HttpPost]
public ActionResult DefaultForm(QuestionViewModel viewModel, string tbButton)
{
    if (ModelState.IsValid)
    {
        try
        {
            if (tbButton.Equals("questsend"))
            {
                return RedirectToAction("Verify", viewModel);
            }
            else if (tbButton.Equals("questupload"))
            {
                //write to DB
                return View(viewModel);
            }
            else
            {
                 dropdownPopulate(viewModel);
                 return View("DefaultForm", viewModel);
            }
        }
        catch
        {
            dropdownPopulate(viewModel);
            return View(viewModel);
        }
    }
    else
    {
        dropdownPopulate(viewModel);
        return View(viewModel);
    }
}

【问题讨论】:

  • 我不明白为什么 View2 的 HttpGet 有 QuestionViewModel 参数。请在 HttpGet 中显示 View1 的 HttpPost 代码和 View2 中 return View(viewModel); 之前的代码。
  • @ekad My View1 是用户填写数据的表单。然后 httppost 控制器将其重定向到 view2,用户可以在其中说出一切是否正确,或者他是否想返回并更正某些内容。 view2 中的viewModel-Parameter 是因为我需要 viewmodel 中的数据才能将其显示给用户

标签: c# asp.net-mvc


【解决方案1】:

问题是你使用Html.DisplayFor在View2中显示viewModel的属性值,所以这些值不会被提交给HttpPost方法,因此在执行View2的HttpPost时viewModel为null。只会提交 &lt;input&gt;&lt;textarea&gt;&lt;select&gt; 标记中的值。

您可以通过在Html.BeginForm 中为viewModel 的所有属性添加Html.HiddenFor 来将viewModel 的值提交到View2 的HttpPost。您还应该使用Html.CheckBoxFor(m =&gt; m.NutzungsbedingungenAngenommen) 作为复选框。像下面这样的东西应该可以工作

@using (Html.BeginForm("Verify", "QuestionForm", FormMethod.Post, new { id = "verifyform" }))
{
@Html.AntiForgeryToken()
@Html.HiddenFor(m => m.Per_Salutation)
@Html.HiddenFor(m => m.Per_Name_First)
@Html.HiddenFor(m => m.Per_Name_Last)
.... // Html.HiddenFor for the rest of QuestionViewModel properties

....
.... // the rest of your code inside the form tag
.... // remove <input type="checkbox" id="NutzungsbedingungenAngenommen " />

@Html.CheckBoxFor(m => m.NutzungsbedingungenAngenommen)
<button class="btn btn-default" type="submit" name="tbButton" value="questsend">Senden</button>
}

【讨论】:

    【解决方案2】:
    • 确保声明 Razor 应该使用什么模型。

      @model QuestionViewModel
      
    • 确保您的 HTML 输入的名称和 ID 采用 MVC 模型绑定器所需的格式。我建议使用提供的 HtmlHelpers 而不是手动编写输入标签。

      @Html.CheckBoxFor(m => m.Agree)
      
    • 从您的 POST 操作中删除 string tbButton 参数

    【讨论】:

    • 所以我将输入更改为@Html.Checkbox。现在 viewModel.Agree 是真的。其余的仍然为空。
    • 啊,@model QuestionViewModel 定义在页面顶部:D ​​和字符串 Button,我需要。如果我把它拿出来,Visual Studio 会告诉我我已经有一个具有相同参数的成员作为验证(它显然忽略了 Httppost)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多