张贴同一页面时奇怪的剃刀场缓存

时间:2015-03-26 15:49:48

标签: asp.net-mvc razor

情况似乎很简单,但我得到一个非常奇怪的错误。也许有人可以解释为什么?我在下面提供了相关部分的完整代码。

基本理念是:

  • 输入公司编号
  • 使用Companies House Gateway API检索结果
  • 显示公司名称&地址在同一页面上,以便审核

问题是,输入不同的公司编号导致始终显示以前的结果(只是地址线的可变数量发生变化)。

我在控制器和视图中有突破,并且正在返回正确的公司详细信息,但它们不会显示。我从未见过像这样的简单页面出错。

我用硬连线公司取代网关服务以取消该服务,但仍然出错。

帐户控制器(Step1操作)

    [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);
    }

RegisterCompanyViewModel类

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>();
    }
}

Step1.cshtml

@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>
}

注意:

  • 我正在使用最新的MVC&#34;一切&#34;截至昨天。
  • 我甚至在主布局中添加了一个计时器显示,所以我可以确认该页面是完全刷新的(它是)。

进入&#34; 1&#34;后的屏幕截图然后&#34; 2&#34;正如公司编号:

enter image description here

注意新的&#34; 7号线&#34;是可见的,但所有其他字段都有其先前的值:

enter image description here

有关此表单页面重新提交时显示以前字段值的原因的任何想法?

解决方案:

我修改过的代码,基于@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);
    }

现在页面如下所示:

enter image description here

1 个答案:

答案 0 :(得分:4)

这是一种常见的混淆。发布的数据进入ModelState对象,ModelState中的任何内容都会覆盖模型上的任何内容。这是设计的。例如,考虑您正在编辑现有实体的场景,但在编辑中,用户遇到了错误。如果Razor使用了模型的数据,那么当返回视图供用户修复任何问题时,所有编辑都将消失,替换为原始模型数据。通过使ModelState优先,它可确保在再次返回表单时保留发布的数据。

您需要做的是遵循正确的PRG模式(Post-Redirect-Get)。如果初始提交是好的,您将重定向回相同的操作以再次显示它,而不是仅返回视图。这样,ModelState就干净了。