假设我有这个模型:
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实际上是使用我的自定义模型绑定器绑定的,知道它是关键任务。所以有这个解决方案:
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
现在,问题是:其他应用程序和开发人员(您和您的应用程序)如何处理?你更喜欢哪一个?有任何缺点或更好的解决方案吗?
答案 0 :(得分:1)
使用为您引入最多自动化的那个,这样您就不必在我的地方重复相同的代码。正如你已经完成的那样,我会选择 2a ,但要使它有点不同,所以我不会将这些属性放在每个动作上,而是放在整个Controller类上。如果可能的话(至少多数行动要求)。如果您需要排除某些操作,请创建一个单独的操作过滤器,以禁用重定向。