我知道我做错了验证。请说服我停下来:)

时间:2009-09-04 14:53:16

标签: c# .net security validation

首先让我解释一下我目前如何处理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等方法切换到静态类。

现在,我认为上述方法存在问题:

  • 新的团队成员将不得不围绕这个

  • 可能妨碍与第三方代码的集成

  • 例外费用昂贵

  • 从来没有见过这样的东西,我内心保守的是:)

然后我喜欢它:

  • 因为你有价值类型所以非常接近拥有很多专门的原语。

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

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

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

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

4 个答案:

答案 0 :(得分:4)

我也非常喜欢在框架中模仿原始模式的概念,因此我会遵循这一概念并倾向于IpV4Address.Parse("1.2.3.4")(以及TryParse)而非隐式演员。

答案 1 :(得分:4)

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

IPv4Address a = new IPv4Address();

会给你无效的结构(值将为null)。

答案 2 :(得分:0)

似乎很多复杂而没有任何好处。只是因为你的意思并不代表你应该这样做。

而不是返回IP的CheckSyntax(字符串值)(这个方法措辞不好btw)我会有类似的东西

bool IsIP(string)

然后你可以将它放在实用程序类,基类或某个地方的单独抽象中。

答案 3 :(得分:0)

来自MSDN topic on implicit conversions

  

预定义的隐式转换   永远成功,永远不会   要抛出的异常。正确   设计用户定义的隐式   转换应该展示这些   特征

微软本身并不总是遵循这一建议。以下使用System.Xml.Linq.XName的隐式运算符会抛出XmlException:

XName xname = ":";

也许System.Xml.Linq的设计师通过not documenting例外逃脱了它: - )