检查多个输入参数

时间:2016-06-05 16:11:29

标签: c# .net

检查函数的多个输入参数并抛出包含所有无效信息的异常的好方法是什么。我不希望有多个if / case条件。有没有更有效的方法呢?

public async Task<HttpResponseMessage> Get(string clientId, string clientSecret, string userName, string password)
{
    HttpResponseMessage response = null;
    string theMessage = null;

    if (string.IsNullOrEmpty(clientId))
    {
        log.Error(Message);
        return error response;
    } 

    if (string.IsNullOrEmpty(clientSecret))
    {        
        log.Error(Message);
        return error response;
    }
    ...

1 个答案:

答案 0 :(得分:0)

简短的回答是否定的 - 毕竟在某些时候你必须实际检查每个单独的有效值,并且只有你知道该有效性需要什么。

更长的答案是,可以使用自己知道它们是否有效的对象,但是你仍然需要让对象验证它自己,例如clientSecret.IsValid将返回一个可以比较的布尔值。

遵循此模式,您可以使用Linq自动检查列表或其他IEnumerable对象(例如,确保它们都可以从您可能创建的接口继承,称为IValidatable),例如使用Any子句。

if (validatableList.Any(x => x.IsValid)
{
    // Throw exception here
}

你也可以反转它并使用All子句来确认所有对象都通过验证而不是没有失败。

但是,这确实意味着不使用任何不能自我验证的对象,这也意味着您没有收到与导致失败的问题相关的详细错误消息。您可以通过添加一个Errors属性来解决这个问题,该属性可以检索验证中出现的一组错误,但您只需将工作移到别处。

另一种选择是使用配置对象作为方法的参数,并将验证例程构建到:

    public async Task<HttpResponseMessage> Get(MessageConfig config)
    {

        HttpResponseMessage response = null;
        string theMessage = null;

        if (!config.IsValid)
        {
           log.Error(Message);
           return error response;
        } 

           ...........
    }

您还可以构建规则引擎并将各种值传递给验证,例如规则可以这样定义:

        // Must have a name
        var e = new Expression();
        e.Add(new IsNotNullOrEmpty<string>(GetName));
        Validator.AddRule(new RuleSet(e, null, ShowMissingNameError,
            FailureBehaviour.Terminate, ValidationLevel.Fatal));

这虽然只对继承层次结构中的复杂对象有意义,它们都需要知道它们是否有效,并且在编码时必须为每个对象应用一组已知规则。然而,它会使你的外部代码消耗这种验证变得微不足道,例如:

if (!myObject.IsValid)
{
    log.Error(myObject.Errors)
}

在某些时候,无论您决定这样做,都必须单独验证对象,看它们是否符合您为确认有效性而设置的规则,这些规则将根据类型和用途而有所不同。例如,int永远不能为null,但可能需要验证以确认它不小于零。

因此,总而言之,如果您希望无法完全摆脱这项工作,您可以将工作抽象到代码的不同部分。

我希望这有用。