c# - 验证 WCF 和 WebService 方法参数值的最佳方式

标签 c# wcf web-services validation postsharp

我将编写一个验证组件以将其用于不同的项目。我不太熟悉企业库等任何验证框架 VAB , Fluent , CuttingEdge.Conditions还有很多其他人,但是我没有时间与他们所有人一起工作,看看哪个更适合我的目的。

我希望这个组件为我提供两种不同的功能:

首先,我想要一些验证器,如 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 之类的东西应用于我想要的任何方法参数来验证参数,而无需任何额外编码。我知道的一种可能方法是使用 PostSharp 编写方面。在方法开始的地方注入(inject)代码(OnMethodEntry)。我用 Postsharp 完成了 Logging,效果很好。

Microsoft 还向 Perform Input Validation in WCF 引入了 IParameterInspector |它提供了 BeforCall 和 AfterCall 两种方法,但我认为它只适用于 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)) 之类的注释也是一个好主意吗?

提前致谢

最佳答案

是的,我只想看看 PostSharp。 OnMethodBoundaryAspectMethodInterceptionAspect 检查方法的参数(用于说明如何验证的属性)和参数(您要验证的值)。

由于您之前使用过 OnMethodBoundaryAspect,请查看 MethodExecutionArgs 的文档.你可以通过args.Method获取方法信息(返回一个MethodBase,在System.Reflection中)。对其调用 GetParameters(),返回一个 ParameterInfo 数组。在每个 ParameterInfo 对象上,您可以使用 Attributes 属性获取有关属性的信息。

一旦您知道了属性,您就知道要使用哪些验证方法(或者如果您正在创建自己的属性,验证方法可以在那些属性类本身中)。然后你只需要使用 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)
    {
        // ...
    }
}

那不是真正的代码:您必须自己解决的细节。

我喜欢将验证代码放在属性本身中的想法,因为您不必为了添加额外的验证类型而更改方面。

关于c# - 验证 WCF 和 WebService 方法参数值的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11807546/

相关文章:

c# - 如何在类库项目中配置 Entity Framework ?

wcf - 如何使用 GET 请求将对象传递给 RESTful 服务?

c# - 在远程服务器上调试 Web 服务

java - 在 Web 服务 Web 方法中返回 'null'

c# - C# 中带有 If\Else 的 Lambda 表达式

c# - lambda 表达式中的 .Sum()

c# - 如何创建算法或公式来获得组合?

c# - 在 C# restful web 服务中删除 xml 命名空间返回字符串

java - 使 WSDL 文件保持最新

c# - IIS 虚拟文件夹 URL 加密