2

我希望在视图中显示一个 DropDownList,然后在我的模型(ExampleAddSetupDto)中包含一个发送到视图的条目列表以填充下拉列表。这很好,但如果我有一个验证错误并在传入模型中重新显示视图,我的列表现在为空。

下面给出了我的操作(注意:如果 ModelState.IsValid 失败,则会出现问题)。此外,Action 方法的第二个参数可能看起来很奇怪,因为我正在使用 Autofac 将正确的服务注入到方法中)。

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Add(ExampleAddSetupDto add, IServiceAddCommit<IExampleAddSetupDto, IExampleAddCommitDto> service)
    {

        if (ModelState.IsValid)
        {
            var response = service.Create(add);
            if (response.IsValid)
            {
                TempData["message"] = "You successfully added a new Example Entry";
                return View("AddSuccess", response);
            }

            //else errors, so copy the errors over to the ModelState
            response.CopyErrorsToModelState(ModelState, add);
        }

        // Some validation error, so redisplay same view
        return View(add);

    }

我的模型如下所示:

public class ExampleAddSetupDto : IExampleAddSetupDto
{

    [StringLength(50, MinimumLength = 2)]
    public string Name { get; set; }

    public int Option1Id { get; set; }

    public int Option2Id { get; set; }

    //-----------------------------
    //now the properties for the drop down lists 

    public IList<Option1> PosibleEntriesForOption1 { get; set; }
    public IList<Option2> PosibleEntriesForOption2 { get; set; }

}

我的观点是:

@model ServiceLayer.Example.DTOs.ExampleAddSetupDto

@{
    ViewBag.Title = "Add";
}

<h2>Add</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm())
{  
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
    <legend>Add an Example item</legend>

    <div class="editor-label">
        @Html.LabelFor(model => model.Name)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Name)
        @Html.ValidationMessageFor(model => model.Name)
    </div>
    <div class="editor-field">
        @Html.Label("Option1")
        @Html.DropDownListFor(model => model.Option1Id, new SelectList(Model.PosibleEntriesForOption1, "Option1Id", "OptionText"))
        @Html.ValidationMessageFor(model => model.Option1Id)
    </div>
    <div class="editor-field">
        @Html.Label("Option2")
        @Html.DropDownListFor(model => model.Option2Id, new SelectList(Model.PosibleEntriesForOption2, "Option2Id", "OptionText"))
        @Html.ValidationMessageFor(model => model.Option2Id)
    </div>
    <p>
        <input type="submit" value="Create" />
    </p>
</fieldset>

}

我了解我需要将 Model.PosibleEntriesForOption 与表单一起返回。我尝试在视图中使用 Html.HiddenFor 助手返回列表,即

@Html.HiddenFor(model => model.PosibleEntriesForOption1)

但这会引发错误'值'System.Collections.Generic.List`1 [DataClasses.ExampleClasses.Option1]'无效。'。

显然我在这里遗漏了一些东西,我希望能得到一些关于如何返回列表的建议,以便重新显示模型不会导致错误。

4

4 回答 4

1

如果您被迫在两个请求之间保留整个列表,无论出于何种原因,我认为最好的方法是使用:

TempData["EnterUniqueKeyHere"] = PossibleEntriesForOption1;

存储它,然后:

PossibleEntriesForOption1 = TempData["EnterUniqueKeyHere"] as IList<Option1>;

检索它。

请注意,存储在 TempData 中的任何内容都将在单个请求后自动删除。

于 2012-07-05T13:40:35.067 回答
0

如果验证失败,您需要使用值列表加载下拉列表。否则,它将失败。

我相信,当您最初加载视图时,它会执行 HttpGet 方法。在 HttpGet 方法中,您必须绑定 Dropdownlist

当你提交页面时,它会执行 httpPost 方法,如果一切正常,它就会提交。如果验证失败,它将执行 HTTPPost 方法,但找不到任何下拉绑定。

所以试试这个:在你的情况下

 if (ModelState.IsValid)
            {
                var response = service.Create(add);
                if (response.IsValid)
                {
                    TempData["message"] = "You successfully added a new Example Entry";
                    return View("AddSuccess", response);
                }

                //else errors, so copy the errors over to the ModelState
                response.CopyErrorsToModelState(ModelState, add);
            }
    else //if validation fails, you need to reload the dropdown and display your view.
      {
          // populate your dropdown again
              // You can add errors list into ModelState.
              ViewData.ModelState.AddModelError("What is the error", "Error Message, "What needs to be done by user, to get it work");
             return view(add)
      }
于 2012-07-05T13:38:36.580 回答
0

在添加的获取操作中,您将为这 2 个属性创建具有适当值的模型 - PosibleEntriesForOption1 和 PosibleEntriesForOption2 由于这些设置正确且在视图上可用,因此下拉菜单在获取时正确呈现。

现在在 POST 上,当验证失败时,您必须再次设置这些属性。

 if (ModelState.IsValid)
    {
        // Do something
    }

    // before you redisplay the same view
    // set the properties PosibleEntriesForOption1 & PosibleEntriesForOption2

    // Some validation error, so redisplay same view
    return View(add);
于 2012-07-05T15:10:20.787 回答
0

Dan Nixon 的 TempData 技术工作一次,但如果验证再次失败,则 TempData 条目为空。我想我也必须重新加载我的列表。

于 2012-08-16T18:14:42.383 回答