ASP.NET MVC:处理用户输入(可恢复)和缺少数据(不可恢复)错误

时间:2009-10-26 10:26:22

标签: asp.net-mvc

假设我有这个模型:

public class ViewModel
{
  [Required]
  public string UserInput { get; set; }
  [Required]
  public Guid EntityId { get; set; }
}

现在,当UserInput错误时,我想重新显示相同的页面但有验证错误(例如/编辑)。但是,当EntityId出错时,我想重定向到其他页面(例如/ Create)。

我可以在每个控制器内手动执行此操作......

if (!ModelState.IsValidField("EntityId")) { redirect }
//or
if (string.IsNullOrEmpty(data.EntityId)) { redirect }

但它有点无聊并且违反DRY。对几个实体进行成像,使用实体嵌套视图模型......太麻烦了。我最好有类似ModelState.IsValidUserData和ModelState.IsValidCriticalData的东西。但是没有这样的事情。

现在,EntityId实际上是使用我的自定义模型绑定器绑定的,知道它是关键任务。所以有这个解决方案:

  1. 常用字段会像往常一样填充ModelState。
  2. (a)使用引发特殊“CriticalModelErrorException”的自定义模型绑定器绑定关键字段。控制器操作具有[HandleCrirticalError(“action”,“controller')]属性 - 处理严重错误并重定向到给定操作。
  3. (b)使用自定义模型绑定器绑定关键字段,该绑定器设置BaseController.CriticalModelErrors属性(显然所有控制器都是从超级控制器基类派生的)。每个动作都可以自由检查ModelState.IsValid和base.CriticalModelErrors,并根据它自由行动。
  4. (c)使用自定义模型绑定器绑定关键字段,该绑定器设置特殊格式模型状态错误,例如: AddModelError(name,“!CRITICAL!text”;然后基本控制器有检测此类字符串的方法。
  5. 2a示例:

    [HandleCriticalError("Create")] // uses the same controller
    [HandleModelStateError("Edit")] // redisplays page with validation errors
    public ActionResult Edit(ViewModel data)
    {
      // here we know both our data entities and user data are valid and safe
    }
    

    2b示例

    public ActionResult Edit(ViewModel data)
    {
      if (!ModelState.IsValid)
         return View(data);
      if (base.CriticalModelErrors.Count > 0)
         return RedirectToAction("Create");
      // here we know both our data entities and user data are valid and safe
    }
    

    2c示例

    protected bool HasCriticalErrors()
    {
       return ModelState.Any(x => x.Value.Errors.Any(x => x.ErrorMessage.StartsWith("!CRITICAL!")))
    }
    // then same as 2b
    

    现在,问题是:其他应用程序和开发人员(您和您的应用程序)如何处理?你更喜欢哪一个?有任何缺点或更好的解决方案吗?

1 个答案:

答案 0 :(得分:1)

使用为您引入最多自动化的那个,这样您就不必在我的地方重复相同的代码。正如你已经完成的那样,我会选择 2a ,但要使它有点不同,所以我不会将这些属性放在每个动作上,而是放在整个Controller类上。如果可能的话(至少多数行动要求)。如果您需要排除某些操作,请创建一个单独的操作过滤器,以禁用重定向。