情况似乎很简单,但我得到一个非常奇怪的错误。也许有人可以解释为什么?我在下面提供了相关部分的完整代码。
基本理念是:
问题是,输入不同的公司编号导致始终显示以前的结果(只是地址线的可变数量发生变化)。
我在控制器和视图中有突破,并且正在返回正确的公司详细信息,但它们不会显示。我从未见过像这样的简单页面出错。
我用硬连线公司取代网关服务以取消该服务,但仍然出错。
[AllowAnonymous]
public ActionResult Step1()
{
RegisterCompanyViewModel vm = new RegisterCompanyViewModel();
return View(vm);
}
[AllowAnonymous]
[HttpPost]
public ActionResult Step1(RegisterCompanyViewModel model)
{
if (ModelState.IsValid)
{
if (model.CompanyNumber.EndsWith("1"))
{
model.Address = new List<string>() { "Line 1", "line 2", "Line 3"};
model.CompanyName = "Company name 1";
}else if (model.CompanyNumber.EndsWith("2"))
{
model.Address = new List<string>() { "Line 4", "line 5", "Line 6", "Line 7" };
model.CompanyName = "Company name 2";
}
else
{
ModelState.AddModelError("CompanyNumber", "Company number not found");
}
}
return View(model);
}
public class RegisterCompanyViewModel
{
[Display(Name="Company Number")]
public string CompanyNumber { get; set; }
[Display(Name = "Company Name")]
public string CompanyName { get; set; }
[Display(Name = "Address")]
public List<string> Address { get; set; }
public RegisterCompanyViewModel()
{
this.Address = new List<string>();
}
}
@model MvcApplication.Models.RegisterCompanyViewModel
@{
ViewBag.Title = "Step1";
}
<h2>Enter your Company Number</h2>
@using (@Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.CompanyNumber, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(x => Model.CompanyNumber)
@Html.ValidationMessageFor(x => Model.CompanyNumber)
</div>
@Html.ValidationMessageFor(model => model.CompanyNumber, "", new { @class = "text-danger" })
</div>
@if (!string.IsNullOrEmpty(Model.CompanyName))
{
<div class="form-group">
@Html.LabelFor(model => model.CompanyName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(x => Model.CompanyName)
@Html.ValidationMessageFor(x => Model.CompanyName)
</div>
</div>
}
@if (Model.Address.Any())
{
for (int i = 0; i < Model.Address.Count(); i++)
{
<div class="form-group">
@Html.LabelFor(model => model.Address, "Address lines " + i.ToString(), htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(x => Model.Address[i])
@Html.ValidationMessageFor(x => Model.Address[i])
</div>
</div>
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save Details" class="btn btn-default" />
</div>
</div>
}
else
{
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Lookup" class="btn btn-default" />
</div>
</div>
}
</div>
}
注意:
进入&#34; 1&#34;后的屏幕截图然后&#34; 2&#34;正如公司编号:
注意新的&#34; 7号线&#34;是可见的,但所有其他字段都有其先前的值:
有关此表单页面重新提交时显示以前字段值的原因的任何想法?
我修改过的代码,基于@Chris Pratt
的非常有用的解释:
[AllowAnonymous]
public ActionResult Step1([Bind(Prefix="id")]string companyNumber)
{
RegisterCompanyViewModel vm = new RegisterCompanyViewModel();
vm.CompanyNumber = companyNumber;
if (!string.IsNullOrEmpty(companyNumber))
{
Gateway gateway = new Gateway(senderId, password);
var company = gateway.GetCompanyDetails(companyNumber);
if (company != null)
{
vm.CompanyName = company.CompanyName;
vm.Address = company.AddressLines;
}
else
{
ModelState.AddModelError("CompanyNumber", "Company number not found");
}
}
return View(vm);
}
[AllowAnonymous]
[HttpPost]
public ActionResult Step1(RegisterCompanyViewModel model, string action)
{
if (ModelState.IsValid)
{
if (action == "Search for company")
{
return RedirectToAction("Step1", new { id = model.CompanyNumber });
}
else if (action == "Save Details")
{
// Save changes now
}
}
return View(model);
}
现在页面如下所示:
答案 0 :(得分:4)
这是一种常见的混淆。发布的数据进入ModelState
对象,ModelState
中的任何内容都会覆盖模型上的任何内容。这是设计的。例如,考虑您正在编辑现有实体的场景,但在编辑中,用户遇到了错误。如果Razor使用了模型的数据,那么当返回视图供用户修复任何问题时,所有编辑都将消失,替换为原始模型数据。通过使ModelState
优先,它可确保在再次返回表单时保留发布的数据。
您需要做的是遵循正确的PRG模式(Post-Redirect-Get)。如果初始提交是好的,您将重定向回相同的操作以再次显示它,而不是仅返回视图。这样,ModelState
就干净了。