使用异常验证 Asp.net MVC 中的业务逻辑

2024-01-28

我对在 asp.net mvc 中用于进行业务规则验证的方法有疑问。

目前我有一个异常类,看起来像这样

public class ValidationException : Exception 
{
    private ModelStateDictionary State { get; set; }
    public ValidationException(ModelStateDictionary state)
    {
        State = state;
    }
    public void MergeModelStates(ModelStateDictionary state)
    {
        state.Merge(this.State);
    }
}

和一个看起来像这样的验证器

public void Validate(IEntity entity)
{
    ModelStateDictionary state = new ModelStateDictionary();
    if (entity.Contact != null && _service.GetBy(entity.Contact.Id) == null)
        state.AddModelError("Contact", "Invalid Contact.");
    if (entity.Title.Length > 8)
        state.AddModelError("title", "Title is too long...");
    ... etc
    if (!state.IsValid)
        throw new ValidationException(state);
}

和一个执行类似操作的控制器

public ActionResult Add()
{
    var entity = new InputModel;
    try
    {
        TryUpdateMode(inputModel);
        ..... Send input to a Repository (Repository calls Validate(entity);
    }
    catch (ValidationException validationException)
    {
       validationException.MergeModelStates(this.ModelState);
       TryUpdateModel(inputModel);
       return View("Add",inputModel);
    }
    return View("List");
}

使用异常来做这样的事情是错误的吗? 有更好方法的例子吗?我真的不想将验证添加到模型实体本身。我见过的唯一其他方法是将控制器 ModelState 注入到存储库层,但这对我来说似乎很草率。

谢谢你的帮助


异常通常应该用于特殊情况,而不是处理程序正常执行期间可能经常发生的事情。造成这种情况的原因有很多——以下是我经常遇到的一些原因:

  1. 性能问题 - 异常通常是相当昂贵的操作 - 如果定期抛出异常,您的性能可能会受到影响。
  2. 处理未捕获的验证异常 - 如果您碰巧使用代码而不处理异常,您将显示验证错误直至“黄屏”或崩溃处理程序 - 可能不是最好的用户体验。
  3. 异常的结构方式无法提供良好的面向用户的信息。看一下异常类 - 没有太多设置可以提供良好的面向用户的信息,而您需要将信息转发回用户。每当我尝试以这种方式使用异常时,我都会得到一大堆带有附加属性的子类,而这些属性对于异常来说并没有多大意义。

我通常喜欢做的一种方法是提供一个公共 Validate 方法,该方法返回错误列表(但从不抛出异常本身),然后提供一个 Save 方法,该方法调用 Validate() 并在出现任何错误时抛出异常。您将行为从“如果模型无效则抛出”切换为“如果代码在模型处于无效状态时尝试保存则抛出”。

为了解决下面有关 Validate 与 Save 中抛出的性能的评论 - 在 Save() 中抛出将具有与在 Validate() 中抛出完全相同的性能损失。然而,关键的区别是这种情况永远不应该发生——您是在防止开发人员不正确地使用您的类,而不是使用异常作为验证方法。如果编写正确,调用 save 方法的代码应类似于:

ValidationResult result = obj.Validate();
if (result.IsValid) {
   obj.Save();
} else {
   // display errors to the user
}

仅当开发人员在保存之前忘记检查验证状态时才会引发异常。这样做的好处是既可以在不使用异常的情况下进行验证,又可以通过不允许保存无效实体来保护数据库。理想情况下,您根本不会捕获控制器中的异常,并让一般错误处理例程处理它,因为问题不再是用户输入,而是开发人员的错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用异常验证 Asp.net MVC 中的业务逻辑 的相关文章

  • 在 ASP.NET MVC 中强制使用 Json() 中的小写属性名称

    鉴于以下课程 public class Result public bool Success get set public string Message get set 我将在控制器操作中返回其中之一 如下所示 return Json ne
  • MVC3 TextBoxFor 带有编码文本

    有没有办法将 TextBoxFor 助手与编码文本一起使用 例如 当使用 MVC3 With Razor 视图引擎的以下帮助程序时 Html TextBoxFor model gt model Description 并且对 model D
  • .net 4.7 中的依赖注入?

    我对 DI 有哪些集成选项有点困惑 我发现它对于 net core 对于我的特定项目 来说非常简单 但我不需要构建跨平台应用程序 也看不到使用 core 的优势 但是 net 框架应用程序似乎仍然使用 Global asax 设置且没有 S
  • C# SMTP 身份验证失败,但凭据正确

    这是我的问题 我编写了以下程序来测试是否可以发送电子邮件 class Program static void Main string args try Console WriteLine Mail To MailAddress to new
  • Owin 声明 - 添加多个 ClaimTypes.Role

    我有一个应用程序 可以在其中为用户分配以下角色 超级管理员 Admin User 一个用户可能分配了两个或多个角色 例如 超级管理员和用户 我的应用程序使用声明 因此我也想通过声明来验证用户角色 喜欢 Authorize Roles Adm
  • 服务层设计。将事物放入服务层的原因

    我有一些与设计相关的问题 should service layer interfaces居住在一个domain layer 例如user service 将代码部分移动到单独层的主要原因是什么 should service layer居住在
  • 为什么自定义类型变量不保存值MVC

    我正在尝试使用 MVC 5 构建一个网站 我有一个包含 3 个变量的控制器类 public class WorkerController Controller public ViewModel viewModel new ViewModel
  • AutoMapper.Mapper 不包含 CreateMap 的定义

    这可能是一个基本问题 但想知道我没有得到 AutoMapper Mapper CreateMap 方法 我使用了错误的 AutoMapper 参考 包吗 谢谢 静态版本CreateMap方法在 4 2 中已弃用 然后在版本 5 0 中从 A
  • ASP.NET MVC 中 ModelState.AddModelError 中的关键参数有什么意义?

    我在我的控制器中添加了验证检查来修改ModelState如果验证失败 例如 private bool ValidateMoney string raw string name decimal min decimal max try var
  • Play Framework 2.3 (Scala) 中的自定义 JSON 验证约束

    我设法使用自定义约束实现表单验证 但现在我想对 JSON 数据执行相同的操作 如何将自定义验证规则应用于 JSON 解析器 示例 客户端的 POST 请求包含用户名 username 我不仅要确保该参数是非空文本 而且还要确保该用户确实存在
  • MVC 项目中的 .Rdlc 报告 - 托管调试助手“PInvokeStackImbalance”

    我即将完成并运行我的上一份报告 我在其他报告中没有遇到过这个问题 我正在尝试根据数据库记录创建报告 当我通过 LocalReport 创建报告并为报告创建参数时 收到错误消息 托管调试助手 PInvokeStackImbalance 调用
  • asp.net mvc:将 RedirectToAction(string, object) 转换为 RedirectToAction(x => x.Detail(id))

    任何人都知道如何创建一个方法 我将把它放在扩展类中 该方法将仅使用表达式 无魔术字符串 与 mvc 的 RedirectToAction 执行相同的操作 所以不要写这样的东西 RedirectToAction Detail new Rout
  • 使用实体框架重叠约会

    我将 asp net mvc 与实体框架一起使用 我有一个包含 startat 字段 endat 字段和 roomid 字段 称为 SpaceConfigurationId 的约会列表 并且希望查找给定房间已重复预订的约会列表 可以假设 e
  • (VS2017)运行所选代码生成器时出错:“序列不包含元素”

    我正在跑过微软的教程之一 https learn microsoft com en us aspnet core tutorials first mvc app 关于 MVC 开发 我在尝试创建各种元素时遇到错误 视图 控制器等 我收到的错
  • MVC 模式中的验证层

    验证模型将使用的数据的最佳位置在哪里 例如 考虑登记表 我们有一些来自注册表的数据 那么验证这些数据的最佳位置在哪里 我们应该通过 if 语句或特殊的验证器类来检查每个数据 这意味着大量的编码 所以我想了解在哪里可以做到这一点 在控制器中
  • Angular 模板验证表单

    我正在研究表单验证 我正在使用模板驱动的验证表单 其编码如下 现在工作正常 但是当我尝试添加时 username ngModel and password ngModel 在创建验证类的输入中 它向我显示一个错误 也请找到该错误 div c
  • Ajax 表单从 Jquery 对话框内重定向页面

    我在部分视图中有一个 jquery 对话框 model JQueryDialogPoc Models FeedBack using Ajax BeginForm GiveFeedback Home null new AjaxOptions
  • Asp.net MVC 路由 - 防止通过约束路由到 XML 文件

    我正在尝试找到一种方法来阻止用户访问特定的 xml 文件 我尝试过做 routes MapRoute SiteMap SiteMap siteMap xml new new isLocal new LocalHostRouteConstra
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • JQuery Mobile 与 MVC 的链接

    我正在使用 ASP NET MVC 3 和 Razor UI 设置 JQuery 移动网站 我正在生成我的链接 例如 a href See Group 2 a 假设我从 Home Index 访问它 我遇到的问题是 当我点击链接时 它会出现

随机推荐