错误消息与引发异常 C# ASP.Net

发布于 2024-08-05 17:00:42 字数 568 浏览 1 评论 0原文

在许多情况下,在 Web 应用程序中,您需要返回错误消息,而不是简单的真/假结果。人们会为此使用异常,但我认为异常是异常行为的一种指示。让我们以 User 类的 Register() 函数为例。如果成功,我们可以简单地返回 true,但如果出现问题,我们想知道到底是什么:“密码不匹配”、“电子邮件格式无效”等等(可能是错误代码)一条消息,并不重要)。

问题是在 C# 和 .Net 中返回此类错误消息的最佳实践是什么?可能有一个准备好的结构,例如:

public struct Result {
    public bool OK;
    public string Message;
}

或者也许我应该在函数中使用参数?就像注册(输出字符串消息)一样。

更新。这几乎描述了我需要的一切:http://blogs。 msdn.com/kcwalina/archive/2005/03/16/396787.aspx

In many cases in web applications you would need to return an error message, rather than simple true/false result. One would use exceptions for that, but I consider exceptions to be an indication of, you know, exceptional behavior. Let's take a Register() function for a class User for instance. If it was successful we can simply return true, but if something went wrong we would like to know what exactly: "passwords don't match", "e-mail is in invalid format" and so on (could be an error code instead of a message, doesn't matter).

The question is what is the best practice for returning such error messages in C# and .Net? There might be a struct ready, something like:

public struct Result {
    public bool OK;
    public string Message;
}

Or perhaps I should just use a parameter in the function? Like Register(out string Message).

Update. This pretty much describes everything I need: http://blogs.msdn.com/kcwalina/archive/2005/03/16/396787.aspx

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

春风十里 2024-08-12 17:00:42

如果是出于验证目的,我会推荐您优秀的 Fluent Validation 库。

引用自该网站:

using FluentValidation;

public class CustomerValidator: AbstractValidator<Customer> {
  public CustomerValidator() {
    RuleFor(customer => customer.Surname).NotEmpty();
    RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
    RuleFor(customer => customer.Company).NotNull();
    RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
    RuleFor(customer => customer.Address).Length(20, 250);
    RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
  }

  private bool BeAValidPostcode(string postcode) {
    // custom postcode validating logic goes here
  }
}

Customer customer = new Customer();
CustomerValidator validator = new CustomerValidator();
ValidationResult results = validator.Validate(customer);

bool validationSucceeded = results.IsValid;
IList<ValidationFailure> failures = results.Errors;

If it's for validation purposes I would recommend you the excellent Fluent Validation library.

Quote from the site:

using FluentValidation;

public class CustomerValidator: AbstractValidator<Customer> {
  public CustomerValidator() {
    RuleFor(customer => customer.Surname).NotEmpty();
    RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
    RuleFor(customer => customer.Company).NotNull();
    RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
    RuleFor(customer => customer.Address).Length(20, 250);
    RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
  }

  private bool BeAValidPostcode(string postcode) {
    // custom postcode validating logic goes here
  }
}

Customer customer = new Customer();
CustomerValidator validator = new CustomerValidator();
ValidationResult results = validator.Validate(customer);

bool validationSucceeded = results.IsValid;
IList<ValidationFailure> failures = results.Errors;
温馨耳语 2024-08-12 17:00:42

我认为这里可以而且应该使用异常。

您可以将 Register() 调用放在 try/catch 块中,从而防止应用程序执行停止。在 catch 块中,您将分析到底出了什么问题并返回适当的消息。

I think exceptions can and should be used here.

You can put your Register() call in a try/catch block therefore preventing application execution stop. In the catch block you will analyze what exactly got wrong and return an appropriate message.

橙幽之幻 2024-08-12 17:00:42

我认为当涉及到程序错误和IO通信时应该使用异常。
这意味着:

  • 未经验证的输入

  • 软件中的错误。 (向字典添加 2 个等号键)

  • 磁盘访问/网络/跨应用程序/等

对于 Register 方法,我应该使用布尔值进行结果检查。

if(Register("someone", "password"))
{
  // success
}
else
{
  // failed
}

或者,如果您想要有关结果的更多详细信息,请指定结果枚举:

public enum RegisterResult
{
  Success,
  BadUsernamePassword,
  PasswordTooShort
}

RegisterResult result = Register("someone", "password");

switch(result)
{
  case(RegisterResult.Success):
    // success
    break;
  case(RegisterResult.BadUsernamePassword):
    // failed
    break;
  case(RegisterResult.PasswordTooShort):
    // failed
    break;
}

如果您需要更多信息(例如 userId),您应该将其定义为输出参数

int userId = 0;

RegisterResult result = Register("someone", "password", out userId);

等...

因此,如果引发异常,则意味着三件事之一。

  • 某些输入(由用户)未经验证。 '(程序员的疏忽)

  • 其中存在错误。 (例如访问已处理的对象或严重的事情等)

  • 存在 IO 问题。 (与数据库的连接丢失..等)

我建议您仅在特殊情况下使用异常。错误的登录不是例外,而是用户的错误。

问候,
杰罗恩

I think exception should be used when it comes to program mistakes and IO communication.
This means:

  • non-validated input

  • a bug in the software. (adding 2 equal keys to dictionaries)

  • disk access/network/cross application/ etc

For a Register method i should either use a boolean for result checking.

if(Register("someone", "password"))
{
  // success
}
else
{
  // failed
}

or if you like more details on the result, specify a result enum:

public enum RegisterResult
{
  Success,
  BadUsernamePassword,
  PasswordTooShort
}

RegisterResult result = Register("someone", "password");

switch(result)
{
  case(RegisterResult.Success):
    // success
    break;
  case(RegisterResult.BadUsernamePassword):
    // failed
    break;
  case(RegisterResult.PasswordTooShort):
    // failed
    break;
}

If you need more information like a userId, you should define it as a output parameter

int userId = 0;

RegisterResult result = Register("someone", "password", out userId);

etc...

So if an exception is thrown, this means 1 of 3 things.

  • Some of the input (by user) is not validated. ' (negligence of the programmer)

  • There is bug in it. (like accessing disposed objects or something serious. etc.)

  • There is an IO problem. (connecting lost from database.. etc)

I advice u to use exceptions only in exceptional situations. A bad login isn't an exception, it's a user fault.

Regards,
Jeroen

旧人 2024-08-12 17:00:42

抛出异常会增加 CPU 利用率,同时添加所有调用堆栈并设置异常类的其他字段。

我不想抛出异常。如果它确实是偶然的错误,比如 Argument 为 null,我会选择带有 ExceptionMessage 字段的结构。

但最好在调用方法之前进行类型值检查,并期望从方法返回原始类型,因为您需要返回布尔值。

Throwing exceptions creates CPU utilization while adding all call stack and setting other fields of exception class.

I prefer not to throw Exceptions. If it is really casual error like say Argument is null,i would go for struct with an ExceptionMessage field with it.

But it is better to type-value check before calling a method and expecting primitive types to return from the method since you need a boolean value return to.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文