5

さまざまなプロジェクトで使用する検証コンポーネントを作成します。Enterprise Library VABFluentCuttingEdge.Conditionsなどの検証フレームワークにはあまり詳しくありませんが、それらすべてを使用して自分の目的に適したものを確認する時間はありません。

このコンポーネントに 2 つの異なる機能を提供してもらいたい:

まず、EmailValidator、StringLengthValidator、MyCustomValidator などのバリデーターを用意して、以下のようにコード内でいつでも使用できるようにします。

public class EmailValidator : RegexValidator // or StringValidator or whatever!
{
    public EmailValidator() : base("emailRegexHere")
    {
    }
public bool override DoValidate(string value)
    {
        return base.DoValidate(value);
    }
}
...

public void MyMethod(string email)
{
    EmailValidator validator = new EmailValidator();
    if(!validator.Validate(email))
        throw new NotValidatedException("email is invalid.");
    ...
}

次に、必要なメソッド パラメーターに DataAnnotations のようなものを追加のコーディングなしで適用して、パラメーターを検証する必要があります。私が知っている 1 つの可能な方法は、PostSharpを使用してアスペクトを記述し、メソッドの開始位置 (OnMethodEntry) にコードを挿入することです。Postsharp でログを記録しましたが、うまく機能します。

また、Microsoft は、BeforCall と AfterCall の 2 つのメソッドを提供するWCF で入力検証を実行する IParameterInspector を導入していますが、WCFでしか機能しないと思います。

まとめると、次のように WCF または WebService で検証を行う必要があります。

[System.Web.Script.Services.ScriptService]
public class MyServiceClass : System.Web.Services.WebService
{
    [Aspects.Validate]
    [WebMethod(EnableSession = true)]
    public string SubmitComment([Validation.Required]string content,[Validation.Guid] string userId,[Validation.Required] [Validation.Name]string name, [Validation.Email]string email, string ipAddress)
    {
        ...
    }
}

:これは、私が必要とする動作を示すための単なるサンプル コードです。他の提案は大歓迎です。また、Validation.* アノテーションを ValidateParam(typeof(EmailValidator)) のような 1 つのアノテーションに変更することをお勧めしますか?

前もって感謝します

4

1 に答える 1

3

ええ、これについては PostSharp を見てください。OnMethodBoundaryAspectorは、メソッドのMethodInterceptionAspectパラメーター (検証方法を示す属性) と引数 (検証する値) を調べます。

以前に使用したことがあるので、 MethodExecutionArgsOnMethodBoundaryAspectのドキュメントをご覧ください。メソッド情報は( System.Reflection にある を返します) で取得できます。それを呼び出すと、 の配列が返されます。各オブジェクトで、プロパティを使用して属性に関する情報を取得できます。args.MethodMethodBaseGetParameters()ParameterInfoParameterInfoAttributes

属性がわかれば、使用する検証メソッドがわかります (または、独自の属性を作成している場合は、検証メソッドをそれらの属性クラス自体に含めることができます)。args.Arguments次に、引数の値を取得するために使用するだけです。

ここにいくつかの(疑似)コードがあります:

public interface IValidator
{
    void Validate(object value);
}
public class ValidationEmailAttribute : Attribute, IValidator
{
    public Validate(string emailAddress)
    {
        // throw exception or whatever if invalid
    }
}

public class ValidateParametersAspect : OnMethodBoundaryAspect
{
    public override OnEntry(args)
    {
        foreach(i = 0 to args.Method.GetParameters().Count)
        {
            var parameter = args.Method.GetParameters()[i];
            var argument = args.Argument[i]; // get the corresponding argument value
            foreach(attribute in parameter.Attributes)
            {
                var attributeInstance = Activator.CreateType(attribute.Type);
                var validator = (IValidator)attributeInstance;
                validator.Validate(argument);
            }
        }
     }
}

public class MyClass
{
    [ValidateParametersAspect]
    public void SaveEmail([ValidationEmail] string email)
    {
        // ...
    }
}

これは実際のコードではありません。詳細は自分で解決する必要があります。

追加の検証タイプを追加するためにアスペクトを変更する必要がないため、属性自体に検証コードを配置するというアイデアが気に入っています。

于 2012-08-06T14:40:36.503 に答える