I'm refactoring my code and wanted to use the IPAddress.TryParse
method to validate if a string is a valid IPv4 address instead of using regular expressions:
public static bool IsIPv4(string value)
{
IPAddress address;
if (IPAddress.TryParse(value, out address))
{
if (address.AddressFamily == AddressFamily.InterNetwork)
{
return true;
}
}
return false;
}
My unit test is now failing because these input values return true
and get parsed to the following IPAddress
objects:
value = "0.0.0.0" -> address = {0.0.0.0}
value = "255.255.255" -> address = {255.255.0.255}
value = "65536" -> address = {0.1.0.0}
Does this make sense? I can see that 0.0.0.0
is technically a valid IPv4 address, even if it makes no sense for the user to enter that. What about the other two? Why are they converted in the way they are and should I treat them as valid even if it might not be transparent for the user, who maybe just forgot to enter the periods (65536
instead of 6.5.5.36
).
Any help is most appreciated.
The job of IPAddress.TryParse() is not to check if the string is a valid IP address, but whether or not the content of the string can be parsed (i.e.; converted) to a valid IP address.
All of the options in your test cases can in fact be parsed to represent and IP. What it comes down to is that your test cases are valid. The issue is that the data for your test cases are not valid, or you're not using the right tool(s) in your test case to get the expected result.
If you're specifically testing for a valid IPv4, with exactly 4 quads (each being an integer between 0 - 255), and want to avoid regex your could instead split then parse and validate.
public static bool IsIPv4(string value)
{
var octets = value.Split('.');
// if we do not have 4 octets, return false
if (octets.Length!=4) return false;
// for each octet
foreach(var octet in octets)
{
int q;
// if parse fails
// or length of parsed int != length of octet string (i.e.; '1' vs '001')
// or parsed int < 0
// or parsed int > 255
// return false
if (!Int32.TryParse(octet, out q)
|| !q.ToString().Length.Equals(octet.Length)
|| q < 0
|| q > 255) { return false; }
}
return true;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With