【问题标题】:I know I'm doing validation wrong. Please persuade me to stop :)我知道我做错了验证。请说服我停止:)
【发布时间】:2009-09-04 14:53:15
【问题描述】:

首先让我解释一下我目前如何处理验证,例如,对于 IPv4 地址:

public struct IPv4Address {
    private string value;

    private IPv4Address(string value) {
        this.value = value;
    }

    private static IPv4Address CheckSyntax(string value) {
        // If everything's fine...
        return new IPv4Address(value);

        // If something's wrong with the syntax...
        throw new ApplicationException("message");
    }

    public static implicit operator IPv4Address(string value) {
        return CheckSyntax(value);
    }

    public static implicit operator string(IPv4Address address) {
        return address.value;
    }
}

我有一堆这样的结构。

他们通常有额外的私人成员来处理事情,但没有公开公开的方法。

这是一个示例用法:

IPv4Address a;
IPv4Address b = "1.2.3.4";
a = b;
b = "5.6.7.8";

string address = a;

// c contains "1.2.3.4"
IPv4Address c = address;

// See if it's valid
try {
    IPv4Address d = "111.222.333.444";
}
catch (ApplicationException e) {
    // Handle the exception...
}

我可以感觉到这有一些非常令人不安的东西,因此我正在考虑切换到使用 IsIPv4Address 等方法的静态类。

现在,我认为上面的方法有问题:

  • 新的团队成员将不得不对此深思熟虑

  • 它可能会妨碍与第 3 方代码的集成

  • 异常代价高昂

  • 从来没有见过这样的事情,我是一个内心保守的人:)

然后我喜欢它:

  • 非常接近拥有大量专用原语,因为您有值类型。

  • 在实践中,它们通常可以像原始类型一样使用,例如,将上面的结构传递给接受字符串的方法是没有问题的。

  • 而且,我最喜欢的是,您可以在对象之间传递这些结构,并确保它们包含语法上有效的值。这也避免了必须始终检查正确性,如果不必要地检查甚至被遗忘,这可能会很昂贵。

我找不到上述方法的致命缺陷(这里只是初学者),你怎么看?

编辑:您可以从第一行推断,这只是一个示例,我并不是要验证 IP 地址的方法。

【问题讨论】:

  • System.Net.IPAddress 会有什么问题?
  • @Johannes:我想他想知道他的验证架构出了什么问题,而不是这个特定的方法。
  • 你不能只使用 inet_aton (来自 unix linux.about.com/library/cmd/blcmdl3_inet_aton.htm )吗?您的平台上应该存在等价物。请确保支持 IPv6 地址 ;)

标签: c# .net security validation


【解决方案1】:

首先,您应该阅读有关隐式转换的帖子,以及何时使用它(以及为什么在您的场景中使用它不好),您可以开始 here
如果您需要检查方法,它们应该是公共静态的,而不是这种奇怪的结构,除此之外,拥有这些方法允许您选择是否要抛出异常(如.Parse() 方法),或通过返回一些信号应该检查的值(如 .TryParse() 方法)。
除此之外,拥有创建有效对象的静态方法并不意味着您不能使用值类型(结构)而不是类,如果您真的想的话。另外,请记住结构有隐式的空构造函数,你不能“隐藏”,所以即使你的构造也可以这样使用:

IPv4Address a = new IPv4Address();

这会给你无效的结构(值为空)。

【讨论】:

  • 这是一个很好的答案,我选择了这个而不是亚伯拉罕的那个,因为它更完整。不过遗憾的是,很多回答的人甚至都懒得仔细阅读问题。
  • 我发现,如果你想解析 IP 地址,你可以在谷歌上搜索现成的解决方案,你会立即找到,所以我专注于你问题的编程模式部分,我很高兴这是您正在寻找的东西。
【解决方案2】:

我也非常喜欢在框架中模仿原始模式的概念,所以我会坚持下去并倾向于IpV4Address.Parse("1.2.3.4")(以及TryParse)而不是隐式转换。

【讨论】:

    【解决方案3】:

    看起来很复杂,没有任何好处。仅仅因为你可以并不意味着你应该。

    而不是返回 IP 的 CheckSyntax(string value)(此方法措辞不好顺便说一句)我只会有类似

    的东西
    bool IsIP(string)
    

    然后你可以把它放在一个实用程序类、一个基类或一个单独的抽象中。

    【讨论】:

      【解决方案4】:

      来自MSDN topic on implicit conversions

      预定义的隐式转换 总是成功,从不导致 要抛出的异常。适当地 设计用户自定义隐式 转换应该展示这些 也有特点

      Microsoft 本身并不总是遵循此建议。以下使用 System.Xml.Linq.XName 的隐式运算符会引发 XmlException:

      XName xname = ":";
      

      也许System.Xml.Linq 的设计者通过not documenting 侥幸逃脱了它 :-)

      【讨论】:

        猜你喜欢
        • 2021-01-05
        • 2014-02-16
        • 2012-08-28
        • 1970-01-01
        • 2021-08-24
        • 2011-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多