我希望在视图中显示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]'的值无效。'。
显然我在这里遗漏了一些东西,我很感激有关如何返回列表的一些建议,以便重新显示模型不会导致错误。
答案 0 :(得分:1)
如果您被迫在两个请求之间保留整个列表,无论出于何种原因,我认为最好的方法是使用:
TempData["EnterUniqueKeyHere"] = PossibleEntriesForOption1;
存储它,然后:
PossibleEntriesForOption1 = TempData["EnterUniqueKeyHere"] as IList<Option1>;
检索它。
请注意,存储在TempData中的任何内容都将在单个请求后自动删除。
答案 1 :(得分: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)
}
答案 2 :(得分:0)
在添加的get动作中,您将创建具有这两个属性的适当值的模型 - PosibleEntriesForOption1&amp; PosibleEntriesForOption2 由于这些设置正确&amp;在视图中可用,下拉列表在get上正确呈现。
现在在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);
答案 3 :(得分:0)
Dan Nixon的TempData技术工作一次,但如果验证再次失败,则TempData条目为空。我想我也必须重新加载我的列表。