将验证错误从服务传递到控制器

时间:2013-03-14 13:45:52

标签: c# asp.net validation asp.net-mvc-4

在我的网络应用程序中,我有服务层负责所有逻辑(如注册等)。我想为我的表单实现服务器端验证。问题是我每次捕获无效数据时都不能抛出异常,因为如果用户输入错误的电子邮件和密码,我的服务方法只会在检查电子邮件时抛出异常,并且只有在用户注意到密码错误后才会发现更正的电子邮件和重新提交的表单。我希望我的整个表格立即得到验证。重要的是:我只需要传递错误类型,显示消息必须添加到控制器中的ModelState。我有一些想法,我希望你帮我决定哪一个更好的性能和良好实践的观点(也许没有 - 也许还有另一种解决方案优于我发布的所有解决方案。)

思路:

  1. 收集字典中的错误,然后抛出单个异常 包含键值形式的所有模型错误(例如“密码”,“必须” 是> 5个符号“)。在控制器中我捕获错误,并使用switch()读取所有条目以检测错误类型并向ModelState添加适当的消息。
    • 优点:使用内置的Exception.Data字典
    • 缺点:需要从字符串
    • 中解密错误类型
  2. 与之前类似,但我创建了自定义异常类,它具有额外的字段枚举字典(例如“密码”,ValidationEnum.LessThanFiveSignsError)。
    • 优点:枚举是switch()操作的更优雅的解决方案
    • 缺点:需要实现自定义异常才能执行内置异常类实际可以执行的操作
  3. 使用字典自定义异常,但使用异常而不是枚举 - 我创建类似StringTooShortException和UsernameAlreadyExistsException的类,并将它们添加到字典中(例如“Password”,新的StringTooShortException())。 Switch可能需要检查类型对象...
    • 优点:我使用例外?我想的越多,我就越相信这不是一个好主意......
    • 缺点:传递对象异常子类(包含所有异常类属性和东西)并且只使用该对象的类型信息?
  4. 让我的每个服务方法返回包含{object regularReturnValueDependingOnMethod,MyCustomErrorContainer canBeListOfEnumsOrSomething}的自定义类。这个和以前的想法之间的基本区别是,我不会抛出异常只是为了将我的错误容器带到控制器,我使用适当的工作流程。
    • 优点:不抛出异常,只返回验证错误给控制器,使用适当的工作流来传递值
    • 缺点:为了将验证错误传递回控制器,包装每个方法的返回值是不是太多了?也许验证错误正是这种情况,我应该使用异常来向控制器传递消息(无论消息是什么:文本字符串,或者,在这种情况下,是整个对象)
  5. 不包装返回值,只需在控制器中创建验证错误容器,并将其作为“out”参数传递给服务
    • 优点:简单
    • 缺点:需要在调用任何服务方法之前创建错误容器实例(好的,只是验证输入的那些)。它很优雅吗?
  6. 你怎么看?哪一个最好?我对完成它并不感兴趣。我希望以应该完成的方式完成它。我想学习良好的编程行为:)

    感谢您的帮助:)

    //编辑: 我的最新想法:我可以创建另一个服务方法只是为了验证目的(例如方法:RegisterUser()用于注册,ValidateRegisterUser()用于模型验证,我只需要确保在调用常规方法之前调用验证方法。你觉得怎么样?

0 个答案:

没有答案