Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将验证错误从服务传递到控制器_C#_Asp.net_Validation_Asp.net Mvc 4 - Fatal编程技术网

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

C# 将验证错误从服务传递到控制器,c#,asp.net,validation,asp.net-mvc-4,C#,Asp.net,Validation,Asp.net Mvc 4,在我的web应用程序中,服务层负责所有逻辑(如注册等)。我想为我的表单实现服务器端验证。问题是,我不能每次捕获无效数据时都抛出异常,因为如果用户键入了错误的电子邮件和密码,我的服务方法会在检查电子邮件时立即抛出异常,只有在用户更正电子邮件并重新提交表单后,才会注意到密码错误。我要立即验证我的整个表单。重要的是:我只需要传递错误类型,显示消息必须添加到控制器中的ModelState。我有一些想法,我希望您能帮助我从性能和良好实践的角度来决定哪一个更好(可能没有-可能有另一个解决方案优于我发布的所有

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

想法:

  • 在字典中收集错误,然后引发单个异常 以键值形式包含所有模型错误(例如“密码”,“必须” 超过5个符号)。在控制器中,我捕获错误,并使用switch()读取所有条目,以检测错误类型并向ModelState添加正确的消息。
    • 优点:使用内置的异常数据字典
    • 缺点:需要从字符串中破译错误类型
  • 与前一个类似,但我创建了自定义异常类,它有额外的字段enum dictionary(例如“Password”、ValidationEnum.LessThanFiveSignsError)。
    • 优点:枚举是用于switch()操作的更优雅的解决方案
    • 缺点:需要实现自定义异常来做一些内置异常类实际上可以做的事情
  • 使用字典自定义异常,但使用异常而不是枚举-我创建了StringTooShortException和UsernameAlreadyExistsException之类的类,并将它们添加到字典中(例如“Password”,new StringTooShortException()。开关可能需要检查类型对象。。。
    • 优点:我使用例外?我越想越觉得这不是个好主意
    • 缺点:传递对象异常子类(包含所有异常类属性和内容),并且只使用该对象是什么类型的信息
  • 使我的每个服务方法返回包含{object RegularReturnValueDependengNMethod,MyCustomErrorContainer canBeListOfEnumsOrSomething}的自定义类。这和以前的想法的基本区别在于,我抛出异常并不是为了将错误容器带到控制器,而是使用正确的工作流。
    • 优点:不会引发异常,只是将验证错误返回给控制器,使用适当的工作流传递值
    • 缺点:仅仅为了将验证错误传递回控制器而包装每个方法的返回值不是太多了吗?可能验证错误正是这种情况,我应该使用exception将消息传递给控制器(不管该消息可能是什么:文本字符串,或者在本例中是整个对象)
  • 不要包装返回值,只需在控制器中创建验证错误容器,并将其作为“out”参数传递给服务
    • 优点:简单
    • 缺点:需要在调用任何服务方法之前创建错误容器实例(好的,只需要验证输入的方法)。它优雅吗
  • 你觉得怎么样?哪一个最好?我对完成这件事不感兴趣。我想按应该做的方式去做。我想学习良好的编程行为:)

    谢谢你的帮助:)

    //编辑:
    我的最新想法是:我可以创建另一个服务方法来进行验证(例如,方法:RegisterUser()用于注册,ValidateRegisterUser()用于注册)对于模型验证,我只需要确保在调用常规方法之前调用validation方法。你认为如何?

    你想过使用一些库来处理验证,例如DataAnnotation吗?嗯……我研究了它,但我认为它不会。看,我需要执行更复杂的验证,比如检查在特定情况下,可能会发生用户对用户的事务(检查表单提交期间是否没有人修改ID,并且没有代表其他用户执行操作)。要进行此类验证,需要对服务层和存储库层进行完全访问。我正在使用依赖项注入(Ninject)所以我必须以某种方式将服务实例从控制器传递到自定义dataannotation验证器。