MVC ViewModel HttpPost返回值具有空值

时间:2017-06-06 18:35:11

标签: c# asp.net-mvc

我花了一些时间来解决这个问题。我通过表单HttpPost将ViewModel从我的View传递回Controller。但是,只有SelectedItemId具有值。用户和权限为空。

查看模型UserRightViewModel

public class UserRightViewModel
{
    public string SelectedItemId { get; set; }

    public SelectList Users;

    public List<RightViewModel> Rights { get; set; }
}

查看模型RightsViewModel

public class RightsViewModel
{
    public int ID { get; set; }

    public string Name{ get; set; }

    public bool isSelected { get; set; }    
}

控制器发布

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(UserRightsViewModel _viewModel)
{
   UserRightsViewModel viewModel = _viewModel;
   /*value _viewModel = null for Users and Rights
   /* code stuff */
   return View(viewModel);
}

查看

@model Web.ViewModels.UserRightsViewModel
     @using (Html.BeginForm())
     {
         @Html.AntiForgeryToken()

    <div class="content-wrapper">
        <!-- Content Header (Page header) -->
        <section class="content-header">
            <h1>
                @ViewBag.Title
            </h1>
            @*<ol class="breadcrumb">
                    <li><a href="#"><i class="fa fa-dashboard"></i> Home</a></li>
                    <li><a href="#">Examples</a></li>
                    <li class="active">Blank page</li>
                </ol>*@
        </section>

        <!-- Main content -->
        <section class="content">

            <!-- Default box -->
            <div class="box">
                <div class="box-header with-border">

                    <div class="box-tools pull-right">
                        <button type="button" class="btn btn-box-tool" data-widget="collapse" data-toggle="tooltip" title="Collapse">
                            <i class="fa fa-minus"></i>
                        </button>
                        <button type="button" class="btn btn-box-tool" data-widget="remove" data-toggle="tooltip" title="Remove">
                            <i class="fa fa-times"></i>
                        </button>
                    </div>
                </div>

        <br />
                <div class="form-group">
                    @Html.LabelFor(model => model.SelectedItemId, "User", new { @class = "control-label col-md-2" })
                    <div class="col-md-10">
                        @Html.DropDownListFor(m => m.SelectedItemId, Model.Users, new { onchange = "redirect(this.value)", @class = "form-control" })
                        @Html.ValidationMessageFor(model => model.SelectedItemId)
                    </div>
                </div>
                <br />

          <div class="box-body">

                    @for (int i = 0; i < Model.Rights.Count(); i += 2)
                    {
                        <div class="row form-group">
                            <div class="col-md-6">
                                <div class="row">
                                    <div class="col-md-4">
                                        <div class="col-md-6">

                                        </div>
                                        <div class="col-md-6">
                                            @Html.CheckBoxFor(model => model.Rights.ElementAt(i).isSelected, new { @class = "checkbox checkbox-center" })
                                            @Html.ValidationMessageFor(model => model.Rights.ElementAt(i).isSelected, "", new { @class = "text-danger" })
                                        </div>
                                    </div>
                                    <div class="col-md-8">

                                        @Model.Rights.ElementAt(i).Denumire
                                    </div>
                                </div>

                            </div>
                            <div class="col-md-6">
                                <div class="row">
                                    <div class="col-md-4">
                                        <div class="col-md-6">

                                        </div>
                                        <div class="col-md-6">
                                            @Html.CheckBoxFor(model => model.Rights.ElementAt(i + 1).isSelected, new { @class = "checkbox checkbox-center" })
                                            @Html.ValidationMessageFor(model => model.Rights.ElementAt(i + 1).isSelected, "", new { @class = "text-danger" })
                                        </div>
                                    </div>
                                    <div class="col-md-8">
                                        @Model.Rights.ElementAt(i + 1).Name
                                    </div>
                                </div>
                            </div>
                        </div>

                    }
                    <br />
                    <br />
                    <div class="form-group">
                        <div class="row">
                            <div class="col-md-6">
                                <div class="col-md-9">

                                </div>
                                <div class="col-md-3">
                                    <input type="submit" value="Save" class="btn btn-primary" />
                                </div>
                            </div>
                            <div class="col-md-6">
                                @Html.ActionLink("Cancel", "Index", null, new { @class = "btn btn-danger" })
                            </div>
                        </div>
                    </div>
                </div>
               </div>
        </section>
    </div>
}

我不知道为什么有些值为null。为什么有些值被发送而有些值没有?

3 个答案:

答案 0 :(得分:1)

Usersnull,因为您不是(也不应该)为SelectListItem中的每个SelectList的每个属性创建和输入(如果您需要返回查看您在POST方法中重新填充值)。在任何情况下,它都是一个字段,而不是一个属性(没有{ get; set; })所以DefaultModelBinder无法设置它。)

Rights为空,因为您无法使用.ElementAt()为集合生成表单控件(检查生成的html,您会看到name属性与您的模型没有关系)。名称属性必须是

<input name="Rights[0].ID" ... />
<input name="Rights[0].Name" ... />
<input name="Rights[0].isSelected" ... />
<input name="Rights[1].ID" ... />
<input name="Rights[1].Name" ... />
<input name="Rights[1].isSelected" ... />
....

请注意,您只为isSelected属性生成一个控件,它本身在POST方法中毫无意义,您最不希望包含ID属性的隐藏输入。

从您的代码中可以看出,您希望生成一个2列布局,在这种情况下,您的代码应该是(简化的)

<div class="row form-group">
    @for(int i = 0; i < Model.Rights.Count; i++)
    {
        <div class="col-md-6">
            @Html.HiddenFor(m => m.Rights[0].ID)
            @Html.CheckBoxFor(m => m.Rights[0].isSelected)
        </div>
        // End current 'row' and start a new one every 2nd item
        if ((i + 1) % 2 == 0)
        {
            @:</div><div class="row form-group">
        }
    }
</div>

答案 1 :(得分:0)

您好,我的回答是您的疑问,有些值是张贴,有些值不是。

实际上你得到了正确的结果,一切都很完美

我说这是因为,如果你将selectedid和selectlistitem绑定到dropdownlist for helper,那么你将只获得被指定为dropdownlist控件名称的selectedid。所以当发布时,浏览器已经发送了名称对。

这也与复选框的原因相同,哪个属性已绑定到只有您将在帖子中获取的名称。

希望以上信息有用

由于

KARTHIK

答案 2 :(得分:-1)

我可以看到你把提交按钮放在窗体外面。所以不要提交财产。