1

System.FormatException: Input string was not in a correct format. it is because the input expected should be numbers only but my input must be in the format of 555-555-5555 that is a requirement. here is my js to do so:

$(window).load(function () {

            $("#phoneNumber").inputmask("***-***-****");
        });

And here is my C# to render the value in this format (555)555-5555, the issue happens here

 public static string phoneFormat(string phone)
        {

            //string[] splitNr = phone.Split('-');
           // return ("(" + splitNr[0] + ")" + splitNr[1] + "-" + splitNr[2]);
             string[] number = phone.Split();

            return string.Format("{0:(###) ### - ####}",ulong.Parse(phone));//ERROR
        }

if i use the commented out part it works but i want to use the parse way. How do i remove the "-" in C# after user input it in the UI and then display the number in this format (555)555-5555. Thank you

CountLessQ
  • 181
  • 1
  • 11
  • 1
    Possible duplicate of [Remove characters from C# string](https://stackoverflow.com/questions/7411438/remove-characters-from-c-sharp-string) – Heretic Monkey Feb 18 '19 at 21:29
  • _Avoid input masks._ It's bad UX. Let users put what they want into fields. Use js to provide prompt feedback to users on whether it will be accepted, but this should be _permissive_. If I type in 5555555555, 555.555.5555 or (555)555-5555 instead of the 555-555-5555 mask, your software should be able to know what I mean. Then use server code (C#) to ensure your js validation wasn't subverted, to normalize the data for storage, and to format data before showing it back to the user. I know there are a lot of sites out there that don't do this, but you don't have to follow their bad example. – Joel Coehoorn Feb 18 '19 at 21:37
  • 2
    _Phone numbers are not integers_: they are strings which contain digits, like credit card numbers, eg. Do not convert them to/from integers. – user2864740 Feb 18 '19 at 22:13

2 Answers2

1

It is easier to handle it as a string instead of trying to parse and then format it as number:

return Regex.Replace(phone, @"(\d{3})-(\d{3})-(\d{4})", "($1) $2 - $3")
Xiaoy312
  • 14,292
  • 1
  • 32
  • 44
  • Thank you, I cam across the Regex but i didn't know how to use it, thank you for making it easy and simple. – CountLessQ Feb 18 '19 at 21:41
1

For fun we can do this:

return string.Format("{0:(###) ### - ####}",ulong.Parse(phone.Replace("-", "")));

But what I'd really do is remove the input mask. Yes, use html/javascript to help the user put in good data, but do so in a way that's much more permissive. If I put in 5551234567, 555.123.4567, (555)123-4567, or even much worse, you should be able to handle any of those.
Input masks are usually bad UI/UX.

On the C# end, I'd really separate this into two parts: normalization, where I clean up potentially messy input for storage and validation, and formatting, where I take the normalized data and format it for display. The reason for two steps is because it's often much more efficient in terms of storage and indexing to store a basic (unformatted) value. Even better, sometimes users want to see the same data represented in different ways. Now it's easy for me to have different format options for the same value. Some people will also include validation as it's own phase, but I like to do this as part of normalizing the data.

Thus, for a really basic phone number, I'd handle the code like this:

public static string NormalizePhone(string phone)
{
    // **We should give the user the benefit of the doubt.**
    // I don't care what crazy format they used, if there are 10 digits, we can handle it.

    //remove anything not a digit
    var digits = Regex.Replace(phone, @"[^\d]", ""); 

    //ensure exactly 10 characters remain
    if (digits.Length != 10) throw new InvalidArgumentException($"{phone} is not a valid phone number in this system.");

    return digits;
}

// Phone argument should be pre-normalized,
//    because we want to be able to use this method with strings retrieved
//    from storage without having to re-normalize them every time.
//    Remember, you'll show a repeat value more often than you receive new values.
public static string FormatPhone(string phone)
{
    //Even better if you have an Assert() here that can show phone is always pre-normalized in testing, but works to a no-op in production.

    return Regex.Replace(phone, @"(\d{3})(\d{3})(\d{4})", "($1) $2 - $3");
}

Now your existing code can call them together:

try 
{
     FormatPhone(NormalizePhone(phone));
}
catch(InvalidArgumentException ex)
{
    // This won't happen often.
    // The html/js layer should stop it in most cases,
    // such that we meet the rule of reserving exception handling for actual exceptional events.
    // But you'll still want to add a meaningful handler here.
}

But really, I would call NormalizePhone() by itself, to have that raw value ready to save to the user's record, and then FormatPhone() afterwards, to show the user on the screen.

Finally, this is a simplistic port. Real phone number validation can be quite complicated. The link is pretty much the standard work in the area, and it's a whopping 12Mb of raw code.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794