【问题标题】:Show ModelState errors in the View only on form POST仅在表单 POST 上的视图中显示 ModelState 错误
【发布时间】:2013-03-10 00:37:03
【问题描述】:

我有一个多步骤注册表:

第 1 页(电子邮件)-> 第 2 页(姓名)-> 第 3 页(成功)

在我的第 1 页上,可以通过查询字符串预先填充电子邮件字段。

问题出在第 2 页上,如果名称字段为空并提交,我无法显示验证错误。

如果我将所需属性应用于第 2 页模型的名称字段,则第 1 页 -> 第 2 页调用将始终失败。所以我取出了所需的属性并为第 3 页创建了一个重复的视图模型,与第 2 页相同,但名称上有所需的属性。现在第 3 页可以检测名称是否为空且模型无效,所以此时我重定向回第 2 页,但第 2 页的视图不会显示名称字段周围的验证错误。

我能做什么?

ViewModel 代码:

public Class StepOneViewModel
{
    [Required]
    public string Email{ get; set; }
}


public Class StepTwoViewModel
{
    [Required]
    public string Email{ get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }
}

public Class StepTwoViewModelPOST
{
    [Required]
    public string Email{ get; set; }

    [Required]
    [Display(Name = "First Name")]
    public string FirstName { get; set; }

    [Required]
    [Display(Name = "Last Name")]
    public string LastName { get; set; }
}

控制器代码:

        public ActionResult Step1(string email)
        {
           return View();
        }

        [HttpPost]
        public ActionResult Step1(StepOneViewModel viewModel)
        {
            if (!ModelState.IsValid)
                return View();
            else
                return RedirectToAction("Step2", viewModel);
        }

        public ActionResult Step2(StepTwoViewModel viewModel)
        {
            if (!ModelState.IsValid)
                return RedirectToAction("Step1", viewModel);
            else
            {
                return View(viewModel);
            }
        }


        [HttpPost]
        public ActionResult Step2(StepTwoViewModelPOST viewModel)
        {
            if (!ModelState.IsValid)
                return RedirectToAction("Step1", viewModel);
            else
            {
                return Content("Success");
            }
        }

【问题讨论】:

  • 为什么不将 page2/Index 发布到 page2/Step2?您可以在发布值时检查模型状态,如果有任何问题,请返回 View("Index", ViewModel)。如果没有错误,则重定向到第3页,
  • 不确定我是否理解您对 page2/index 到 page2/step2 的建议
  • @newbie:我重新格式化了您问题中的代码,因为如果不是很清楚,您很容易错过其中的某些部分。

标签: asp.net asp.net-mvc asp.net-mvc-3 asp.net-mvc-2 asp.net-mvc-4


【解决方案1】:

好的,我想通了...在 Step2 的 POST 处理程序上,如果 ModeState 无效,我只需要映射 StepTwoViewModelPOST => StepTwoViewModel,然后简单地返回带有模型的 View。

  [HttpPost]
    public ActionResult Step2(StepTwoViewModelPOST viewModel)
    {
        if (!ModelState.IsValid)
        {
             StepTwoViewModel model = new StepTwoViewModel { 
                  Email = viewModel.Email,
                  FirstName = viewModel.FirstName,
                  LastName = viewModel.LastName
              };
            return View(model);
        }
        else
        {
            return Content("Success");
        }
    }

【讨论】:

    【解决方案2】:

    这里有“工作流程”问题。做 PRG!

    什么是PRG? Post/Redirect/Get。因此,请尝试使用以下表单工作流程:

    1. 获取步骤 1
    2. POST step1(检查ModelState.IsValid,如果不是返回View
    3. 重定向到第 2 步
    4. 获取步骤 2 5 ...

    有意义吗?

    当然应该在步骤之间保存数据。您可以在客户端(cookie、sesvars、本地存储...)或服务器端(会话、一些持久性)执行此操作。不过我建议您只使用 ASP.NET 会话。

    【讨论】:

    • 这正是我正在做的,PRG!请查看我在问题中发布的代码。
    • 您没有为我的具体问题提供任何解决方案。很想探索除我发布的解决方案之外的任何替代解决方案。讨厌 GET 和 POST 有重复的 ViewModel。
    • 好吧,我猜“第 2 点”给出了看起来的解决方案(检查模型状态)。但是,如果您只想拥有一个 ViewModel,那就拥有它吧!这意味着您不会在每个步骤中使用“整个”视图模型,但您会将所有内容都放在一个地方,因此请尝试像这样拥有它。唯一的问题仍然是在哪里存储步骤数据。幸运的是,我也在回答中提出了一些解决方案。
    猜你喜欢
    • 1970-01-01
    • 2020-03-10
    • 1970-01-01
    • 2020-01-14
    • 1970-01-01
    • 1970-01-01
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多