2009-10-26 56 views
0

假设我有这种模式:ASP.NET MVC:处理用户输入(可恢复)和缺失数据(不可恢复的)错误

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

现在,当UserInput是错误的,我想重新显示相同的页面,但有验证错误(例如/编辑)。然而,当ENTITYID是错误的,我想重定向至其他网页(例如/创建)。

我可以做到这一点手动每个控制器内......

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

,但它是一种枯燥和违反DRY。成像几个实体,实体嵌套视图模型...太麻烦。我还是有一些像ModelState.IsValidUserData和ModelState.IsValidCriticalData。但是没有这样的事情。

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

  1. 通常的字段会像往常一样填充模型状态。
  2. (一)关键领域使用抛出特殊的“CriticalModelErrorException”自定义模型粘合剂粘结。控制器动作有[HandleCrirticalError(“行动”,“控制器')]属性 - 它处理关键错误和重定向到给定动作
  3. (b)中的临界磁场正在使用设置BaseController.CriticalModelErrors属性定制模型粘结剂粘结(显然所有的控制器都从supercontroller基类派生),每个动作是免费检查既ModelState.IsValid和base.CriticalModelErrors并基于该自由运转。
  4. (c)中的临界磁场正在使用设置特殊格式定制模型粘结剂粘结模型状态错误,例如AddModelError(名称,“!CRITICAL!text”;然后基本控制器有检测这样的字符串的方法

2a exa mple:

[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

使用自动化程度最高的,因此您不必在我的地方重复相同的代码。正如你已经做了我会跟2A去,但使它有点不同的,所以我不会把这些属性上的每一个动作,而是对整个控制器类。如果可能的话(如果至少需要多数行动)。如果您需要排除某些操作,请创建一个单独的操作筛选器来禁用重定向。