MVC仅在第一个循环中使列表属性成为必需

时间:2016-01-29 12:00:48

标签: asp.net-mvc

假设我将以下列表属性呈现给我的创建视图:

        @for (var i = 0; i < Model.SiteSplits.Count(); i++)
        {
            <div class="clearfix"></div>
            <div class="form-group">
                @Html.LabelFor(model => model.SiteSplits[i].CostCode, htmlAttributes: new {@class = "control-label col-md-3"})
                <div class="col-md-9">
                    @Html.EditorFor(model => model.SiteSplits[i].CostCode, new {htmlAttributes = new {@class = "form-control"}})
                </div>
            </div>

            <div class="clearfix"></div>
            <div class="form-group">
                @Html.LabelFor(model => model.SiteSplits[i].SplitPercentage, htmlAttributes: new {@class = "control-label col-md-3"})
                <div class="col-md-9">
                    @Html.EditorFor(model => model.SiteSplits[i].SplitPercentage, new {htmlAttributes = new {@class = "form-control"}})
                </div>
            </div>
        }

这会产生x3成本代码和拆分百分比,这些成本代码会在POST列表中传回控制器。

我已在视图模型中的CostCodeSplitPercentage上添加了必需的注释,这导致需要所有3个分组/代码。

有没有办法只在第一个循环中只需要CostCodeSplitPercentage并让它忽略后两个的验证,所以它们只是可选的?

1 个答案:

答案 0 :(得分:1)

要直接回答您的问题,您可以在模型中添加一个附加属性

public bool IsRequired { get; set; }

然后在其他属性上使用foolproof [RequiredIfTrue]或类似的验证属性

[RequiredIfTrue("IsRequired")]
public string CostCode { get; set; }

并在GET方法中,使用3个默认对象填充SiteSplits集合,将第一个设置为IsRequired = true;,并为IsRequired属性添加隐藏输入。

@Html.HiddenFor(m => m.SiteSplits[i].IsRequired)

但是,对于您指明需要1到3件物品的last question,这没有任何意义。如果用户添加全部3,则最后2个将不会被验证,您可能正在保存无效数据。

更好的选择是允许用户根据需要动态添加新项目,这可以通过使用BeginCollectionItem帮助程序或创建html模板并复制并将其附加到您的集合(并更新其收集索引器),如以下答案所述

  1. POST a form array without successful
  2. Submit same Partial View called multiple times data to controller?
  3. Set class validation for dynamic textbox in a table
  4. 使用BeginCollectionItem的示例也包含在this article

    另请参阅this DotNetFiddle,了解基于上一个问题中发布的模型使用html模板的工作示例