URL验证器的实现与应用

在开发Web应用程序时,经常需要在配置文件中设置一些参数,比如URL。如果这些参数的值不正确,可能会导致应用程序运行出错。因此,实现一个URL验证器来确保这些参数是有效的URL,就显得尤为重要。本文将介绍如何在.NET应用程序中实现一个URL验证器,并展示其在实际项目中的应用。

Revalee是一个开源项目,用于为Web应用程序安排回调。在开发过程中,编写了一些内部工具或“小部件”,其中一个就是URL验证器。虽然这个验证器不是项目的核心组件,但它的加入确实让在开发和部署过程中更加轻松。

Revalee是一个免费的开源项目,由所在的开发团队编写。它在GitHub上可以免费获取,并且受到MIT许可的保护。如果感兴趣,可以下载并查看。

为什么需要URL验证器

假设web.config文件中包含了一个自定义配置节,如下所示: <revalee> <clientSettings serviceBaseUri="http://localhost:46200" authorizationKey="YOUR_SECRET_KEY" /> <recurringTasks callbackBaseUri="http://localhost:64646"> <task periodicity="daily" hour="00" minute="00" url="/RevaleeTest/DailyRecurring" /> <task periodicity="hourly" minute="30" url="/RevaleeTest/HourlyRecurring" /> </recurringTasks> </revalee> 现在让关注<clientSettings>元素,特别是serviceBaseUri属性。这个属性显然是一个URL:它有方案、主机,甚至在这个例子中还有一个端口号。可以直接将其作为Uri导入,而不是先作为字符串导入,然后在代码的其他地方将其转换为Uri。希望在应用程序加载时,该属性的值能够作为一个有效的URL进行验证,更具体地说,作为一个Uri。如果该属性的值不是一个有效的URL,那么应用程序就配置错误,无法运行。

定义自定义ConfigurationElement

既然从web.config文件开始,让从那里开始工作,最后再介绍UrlValidator。这意味着需要定义一个自定义的ConfigurationElement,在这个例子中叫做ClientSettingsConfigurationElement。这个类看起来像这样: using System; using System.ComponentModel; using System.Configuration; namespace Revalee.Client.Configuration { internal class ClientSettingsConfigurationElement : ConfigurationElement { [ConfigurationProperty("serviceBaseUri", IsKey = false, IsRequired = false)] [UrlValidator(AllowAbsolute = true, AllowRelative = false)] public Uri ServiceBaseUri { get { return (Uri)this["serviceBaseUri"]; } } // 其他属性省略。 } } 会注意到两个细节。首先,属性(即ServiceBaseUri)被定义为Uri(并且this["serviceBaseUri"]被转换为Uri)。其次,ServiceBaseUri被标记了以下自定义属性(稍后会详细介绍): [UrlValidator(AllowAbsolute = true, AllowRelative = false)] 现在看到了如何使用这样的自定义属性。如何定义它呢?好吧...

定义ConfigurationValidatorAttribute

自定义UrlValidator属性(如上所示)包括两个属性:AllowAbsolute和AllowRelative。现在定义这两个bool属性,当创建自定义ConfigurationValidatorAttribute时。

属性类型定义示例

属性 类型 定义 示例
AllowAbsolute bool 允许(或禁止)使用绝对Uri http://localhost:46200/Absolute/Path
AllowRelative bool 允许(或禁止)使用相对Uri /Relative/Path
由于这个自定义属性的属性都是可选的(注意构造函数的签名没有参数:public UrlValidatorAttribute()),将为每个属性分配一个默认值true。这个新的自定义ConfigurationValidatorAttribute的最终代码如下: using System; using System.Configuration; namespace Revalee.Client.Configuration { internal sealed class UrlValidatorAttribute : ConfigurationValidatorAttribute { private bool _AllowAbsolute = true; private bool _AllowRelative = true; public UrlValidatorAttribute() { } public bool AllowAbsolute { get { return _AllowAbsolute; } set { _AllowAbsolute = value; } } public bool AllowRelative { get { return _AllowRelative; } set { _AllowRelative = value; } } public override ConfigurationValidatorBase ValidatorInstance { get { return new UrlValidator(_AllowAbsolute, _AllowRelative); } } // 'private class UrlValidator'的代码在这里定义(见下文完整类) } } 在上面的代码中,看到了ConfigurationValidatorAttribute基类的ValidatorInstance属性被覆盖,并返回了一个新的UrlValidator()类型:ConfigurationValidatorBase。那个私有类将在注释位置定义(上面)。相反,现在将单独回顾那段代码。

实现ConfigurationValidatorBase

UrlValidator还有其他一些细节定义,但ConfigurationValidatorBase类的Validate()方法是所有自定义验证工作发生的地方。由于这是这项努力的精髓,让关注这一点。

可能已经猜到了,根据本文前面奠定的基础,对支持绝对和相对URL(或只支持其中一个)感兴趣。此外,在这种特定实现中,只对具有http或https方案的绝对Uri感兴趣;如果Uri是相对的,那么不必担心它的方案。所以,不多说了,代码如下: private class UrlValidator : ConfigurationValidatorBase { private bool _AllowAbsolute = true; private bool _AllowRelative = true; public UrlValidator(bool allowAbsolute, bool allowRelative) { _AllowAbsolute = allowAbsolute; _AllowRelative = allowRelative; } public override bool CanValidate(Type type) { return type == typeof(Uri); } public override void Validate(object value) { if (value == null) { return; } if (value.GetType() != typeof(Uri)) { throw new ArgumentException("The URL attribute is invalid."); } Uri url = value as Uri; if (!_AllowAbsolute && url.IsAbsoluteUri) { throw new ArgumentException("The URL attribute cannot contain an absolute URL."); } if (!_AllowRelative && !url.IsAbsoluteUri) { throw new ArgumentException("The URL attribute cannot contain a relative URL."); } if (url.IsAbsoluteUri && url.Scheme != Uri.UriSchemeHttp && url.Scheme != Uri.UriSchemeHttps) { throw new ArgumentException(string.Format("The URL attribute only supports {0} and {1}.", Uri.UriSchemeHttp, Uri.UriSchemeHttps)); } } } ...就是这样。一些一行的if语句,实际上是Validate()方法中的最后三个,是这个特定的UrlValidator的精髓。也许会更复杂。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485