Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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#_Validation_Error Handling - Fatal编程技术网

C# 类定义的错误

C# 类定义的错误,c#,validation,error-handling,C#,Validation,Error Handling,我希望将我的错误分开,因为定义错误时会有很多细节,这是一个错误模型: public interface IErrorResult : IResult { string Code { get; set; } string Message { get; set; } string Description { get; set; } } 使用的示例如下: public static class CheckoutError { public static ErrorRe

我希望将我的错误分开,因为定义错误时会有很多细节,这是一个错误模型:

public interface IErrorResult : IResult
{
    string Code { get; set; }
    string Message { get; set; }
    string Description { get; set; }
}
使用的示例如下:

public static class CheckoutError
{
    public static ErrorResult Purchased = new ErrorResult
    {
        Code = CheckoutErrors.AlreadyPurchased,
        Message = "License already bought.",
        Description = "A license for this account already exists."
    };

    public static ErrorResult Expired = new ErrorResult
    {
        Code = CheckoutErrors.Expired,
        Message = "Checkout Expired.",
        Description = "The checkout session expired, please try again."
    };

    public static ErrorResult NotFound = new ErrorResult
    {
        Code = CheckoutErrors.NotFound,
        Message = "Checkout not found.",
        Description = "This checkout session doesn't exist."
    };
}
我将这些单独定义的原因是,它们可以重用,并且在必要时可以更容易地修改它们

这些错误用于在调用业务逻辑之前调用的验证器,如下所示:

public class CheckoutValidator : ICheckoutValidator
{
    private readonly ICheckoutSessionRepository _checkoutSessionRepository;
    private readonly ILicenseValidator _licenseValidator;

    public CheckoutValidator(ICheckoutSessionRepository checkoutSessionRepository)
    {
        _checkoutSessionRepository = checkoutSessionRepository;
    }

    public async Task<IResult> ValidateSession(string userId)
    {
        var checkout = await _checkoutSessionRepository.GetBySession(userId);
        if (checkout == default(CheckoutSession) || checkout.User.AspNetUserId != userId)
        {
            var error = CheckoutError.NotFound;
            error.Status = ResultStatusEnum.NotFound;
            return error;
        }

        if (DateTime.Now > checkout.Expires)
        {
            var error = CheckoutError.Expired;
            error.Status = ResultStatusEnum.Invalid;
            return error;
        }

        return new Result
        {
            Status = ResultStatusEnum.Valid
        };
    }
}
公共类CheckoutValidator:ICheckoutValidator
{
专用只读ICheckoutSessionRepository _checkoutSessionRepository;
专用只读ILicenseValidator\u licenseValidator;
公共CheckoutValidator(ICheckoutSessionRepository checkoutSessionRepository)
{
_checkoutSessionRepository=checkoutSessionRepository;
}
公共异步任务验证会话(字符串用户ID)
{
var checkout=await _checkoutSessionRepository.GetBySession(userId);
if(checkout==default(CheckoutSession)| checkout.User.AspNetUserId!=userId)
{
var error=CheckoutError.NotFound;
错误。状态=ResultStatusEnum.NotFound;
返回误差;
}
如果(DateTime.Now>checkout.Expires)
{
var error=CheckoutError.Expired;
error.Status=ResultStatusEnum.Invalid;
返回误差;
}
返回新结果
{
状态=ResultStatusEnum.Valid
};
}
}

我在想,这种设计是常用的吗?我觉得它可以变得更简单,我已经把事情复杂化了,但我正在努力寻找哪些地方以及哪些方面可以改变和改进

我已经看到并使用了一些错误模型

成功/失败的替代方案

  • bool Try*(输出结果)
    -模式
  • 返回空值
  • 归还
  • 提供有关故障的附加信息的备选方案

  • 抛出异常
  • 归还
  • 每个选项都有各种缺点/优点。关于,一种观点是,异常应用于“异常”,即意外和罕见错误,而结果对象应用于常见和/或预期错误。内存不足可能是前者的一个例子,而无效用户可能是预期错误的一个例子

    关于您的具体实施,有几个问题:

  • 您的结果对象不是泛型对象,所以如果需要返回任意对象,您将怎么做?调用方似乎必须进行一些转换才能从返回的对象中获得有用的东西,这通常会导致代码混乱。我建议将结果对象设置为通用对象,从中寻找灵感
  • 您有错误是静态(即全局)对象,但有公共设置器。这是一个很容易导致奇怪行为的大禁忌。例如,如果从多个线程访问错误对象(属性随时可能改变),或者如果忘记设置其中一个属性(它将保留最后一个值)。要么使对象不可变,要么将其更改为返回新对象的方法

  • 注意
    error.Status=ResultStatusEnum.NotFound
    因为这会修改
    CheckoutError.NotFound
    实例。@vern您可以修改
    Status
    属性,因为在不同的情况下,结果状态可能会有所不同。然后在控制器中使用它来了解要发送回用户的内容,即
    NotFound()
    BadRequest()
    问题是重复使用同一实例。在并行上下文(如API)中,这可能会产生难以调试的错误。如果一个请求product
    NotFound
    和其他product
    BadRequest
    同时执行,结果是不可预测的。@Vernou我想我不明白,你能提供一个例子吗?@Vernou是因为它是一个静态类吗?我应该换这个吗?