Asp.net mvc编辑器模板Html.HiddenFor值缺失

时间:2016-03-23 14:37:03

标签: asp.net asp.net-mvc mvc-editor-templates

我为我的多选复选框创建了一个名为 UserRoles.cshtml 的编辑器模板。

@model List<UserRoleView>

@{
    var context = Context.GetContainer().Get<ApplicationDbContext>();

    var avaliableRoles = context.Roles.Select(x =>
        new UserRoleView
        {
            Id = x.Id,
            Name = x.Name,
            IsInRole = false
        }).ToList();

    for (var i = 0; i < avaliableRoles.Count; i++)
    {
        @Html.HiddenFor(it => it[i].Id)
        @Html.HiddenFor(it => it[i].Name)
        <div class="checkbox">
            <label>
                @Html.CheckBoxFor(it => it[i].IsInRole)
            </label>
        </div>
    }
}

我使用EditorForModel在 Create.cshtml 中生成了我的表单:

    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)
        @Html.EditorForModel()

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

当我运行应用程序时,我的隐藏值被遗漏了。但是复选框有价值。

enter image description here

enter image description here

2 个答案:

答案 0 :(得分:1)

问题是您应该在视图中使用模型,该模型从控制器传递而不在视图中生成它。您正在将业务逻辑与您的表示逻辑混合,这是非常糟糕的做法。您的控制器方法应该类似于这样,这也确保您的DbContext实例在使用后处理。

public class AccountController : Controller {
    public ActionResult Create() {
        using(var context = Context.GetContainer().Get<ApplicationDbContext>())
        {
            var avaliableRoles = context.Roles.Select(x =>new UserRoleView
            {
                Id = x.Id,
                Name = x.Name,
                IsInRole = false
            }).ToList();

            return View(avaliableRoles);
        }
    }
}

您的观点应该是这样的。

<强> Create.cshtml

@model List<UserRoleView>
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
    @Html.EditorForModel()

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

<强> UserRoles.cshtml

@model UserRoleView
@{
        @Html.HiddenFor(x => x.Id)
        @Html.HiddenFor(x => x.Name)
        <div class="checkbox">
            <label>
                @Html.CheckBoxFor(x => x.IsInRole)
            </label>
        </div>
}

答案 1 :(得分:1)

你的问题在这里:

    @Html.HiddenFor(it => it[i].Id)
    @Html.HiddenFor(it => it[i].Name)

根据您的代码,它应该是:

    @Html.HiddenFor(it => avaliableRoles[i].Id)
    @Html.HiddenFor(it => avaliableRoles[i].Name)

但是如果您使用的是EditorTemplates,则无需为emumerations创建它们。它会像这样工作:

<强> Create.cshtml

@model List<UserRoleView>


//This is actually should be in Controller like Igor mention
@{
    var context = Context.GetContainer().Get<ApplicationDbContext>();
    //here you set your model
    Model = context.Roles.Select(x =>
        new UserRoleView
        {
            Id = x.Id,
            Name = x.Name,
            IsInRole = false
        }).ToList();
}

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
    @Html.EditorForModel() //here you render collection. 

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

UserRoleView.cshtml 如果您实际使用的是EditorTemplates名称应与ViewModel名称相同

@model UserRoleView

@Html.HiddenFor(x => x.Id)
@Html.HiddenFor(x => x.Name)
<div class="checkbox">
   <label>
       @Html.CheckBoxFor(x => x.IsInRole)
   </label>
</div>

并且 Razor明白您的模型是UserRoleView的集合并将其应用于每个项目。