-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TryParse for email addresses #907
Comments
Can you post full API proposal? (see API review process) |
How's that look? |
Ah, I didn't realize you updated top post. |
My apologies, I see how my last comment was a bit ambiguous. |
@Grauenwolf Have you tried writing an extension class to accomplish this task? |
Alternatively, why not make the |
As long as it has a TryParse method, I have no preference. |
@euclid47 @ctolkien I agree with @Grauenwolf that |
The only way to discover if an email is valid is to send an email to it and see what happens. Just because it looks like an email address does not mean it's valid. When you TryParse on a number the result indicates that the value parsed is, or is not, a number. TryParse for email addresses cannot do this. As people make security decisions on email addresses I would not like to see this added. (As an aside I wish System.Net.Mail would just go away). |
My experience is that the only real way to check if an email is valid is to send an email to it. Edit: gah beaten. |
That's like arguing we shouldn't parse someone's date of birth because the only way to know if the DOB is valid is to check the birth certificate. If using for UI validation, you shouldn't wait for a bounce to inform the user they typed "me#google.com". Personally I'm not even using it for sending emails. I'm using it to extract the user and host name as separate fields for LDAP lookups. (Which also proves the email address is valid without sending an email.) |
On another project I need to read the top 10,000 rows from each table and see which non-null columns always, never, or sometimes contain email addresses. Again, I need an email address parser. But I'm not going to be actually sending out emails. Finally, how would you use an email address alone for security? Even if you did send a validation email, it could be to a fake address set up for that purpose. |
You were given an email parser in your Stack Overflow question, so what more do you need really? I'm in agreement with @blowdart here, not keen on adding extra APIs to parse email addresses, especially as the rules for what a valid address has the potential to change, meaning the API would go out of date. |
I fail to see the logic in your argument. Class MailAddress isn't going away. In the unlikely event that the definition of an email address changes, it will have to be updated anyways. And no, a Regex is not a substitute for a standards compliant parser. |
@Grauenwolf For both questions I would ask these on stackoverflow.com due to being off topic. Both questions are important and I have a few ideas to accomplish both tasks. |
@blowdart, @ctolkien, @WiredUK
It can and it definitelly would. You mix two different things here. One is a check if some string represents an email address, the other is if that email address really exists (or is valid as you say). ˙TryParse˙ is about the first one. The same is with The other thing is - if you even send an email to that address, how can you be sure? What if the email server is down? Do you assume in this case that email is invalid?
It is quite unlikely that the format of email address will change, but if it happens, this API will not change. It still will have the same input and output. What would really change is that regex, because it will need to adapt to new format. |
To put it in simpler way |
This is not about searching for some workaround, but it is an API proposal for .NET core. So this is the place where to ask/propose. If you have some ideas, why not share them? |
@satano The two questions about searching through large datasets and using an email address as the only method of security. Both are valid questions but off topic for the original feature request. Those are best suited for stackoverflow.com. |
@euclid47 OK. Thanks. |
I have several projects where this would be useful (today I use the try-catch hack). In my mind this would be very similar to the Uri.TryCreate method which already exists. The idea is to validate the structure, which is then exposed via MailAddress properties like Host. Like with Uri, this of course cannot validate whether the address points to an actual email account. |
I'd be okay with this so long as it allows just about any combination of special characters, as valid email addresses do. I'd be hard-pressed to find a reason to go further than checking something like bool IsValidEmailAddress(string candidate)
{
if (candidate == null) return false;
var trimmed = candidate.Trim();
return trimmed.Length >= 3 && trimmed.IndexOf('@', 1, trimmed.Length - 2) != -1;
} |
@jnm2 presumably this would run the exact same validation as a what the MailAddress constructor already does. |
using System.ComponentModel.DataAnnotations;
public bool IsValidEmail(string source)
{
return new EmailAddressAttribute().IsValid(source);
} Can't someone just port this over? |
@truencoa interesting. Looks like |
well, we tried using URI because that's just simpler, but couldn't figure out a way to parse it with and have our fail tests pass: string emailAddress = "manythings@support@microsoft. com";
Uri uri;
if (Uri.TryCreate(Uri.UriSchemeMailto + Uri.SchemeDelimiter + emailAddress, UriKind.Absolute, out uri))
{
MailAddress mailAddress = new MailAddress(emailAddress);
} Uris are simply too accepting - especially with mailtos. |
Regardless of implementation, I agree this would be a nice addition to the API. First, there is the performance impact. Though probably minimal on today's machines, in a world of micro/nano-services, focus on milliseconds, and the .NET team's attention to performance in general, I feel this is an argument pro. But there is also the fact that it would be easily discoverable. This makes it a good addition to the API in my opinion. |
Open question: Should we add also |
My opinion: that might be good because it follows the structure of |
Consistency is important. And it's easier to use static functions as delegates than constructors. |
My current use case is similar to @Grauenwolf. I am validating a textbox value as its entered. So for each character entered before the email is valid, I get an exception. If I am debugging with break on exception, then it becomes a bit problematic to test. |
That's a good use case, thanks! |
I agree, this is a de-facto pattern established throughout the library and I'd prefer to preserve that. See |
|
triage: we're okay with adding both Parse and TryParse, and think there's enough value (and low effort) for this. New API proposal: public static MailAddress Parse(string address);
public static MailAddress Parse(string address, string displayName);
public static MailAddress Parse(string address, string displayName, Encoding displayNameEncoding);
public static bool TryParse(string address, out MailAddress result);
public static bool TryParse(string address, string displayName, out MailAddress result);
public static bool TryParse(string address, string displayName, Encoding displayNameEncoding, out MailAddress result); |
One reason we've found I see this as comparable to using |
That last question made no sense to me. When I'm checking rows in a database, I'm not going to use a DataAnnotation to detect email addresses. And if the DA validation is rejecting legal email addresses, then it should be fixed. |
#nullable disable
public static bool TryCreate(string address, out MailAddress result);
public static bool TryCreate(string address, string displayName, out MailAddress result);
public static bool TryCreate(string address, string displayName, Encoding displayNameEncoding, out MailAddress result); |
|
@terrajobst @scalablecory I don't think Uri is the best pattern to follow here. Most of the other types in .NET follow the Parse/TryParse pattern. |
The feedback API review had for this was that this does not follow public static bool TryParse(string address, string displayName, Encoding displayNameEncoding, out MailAddress result);
The suggestion to use I hope this gives some context. @Grauenwolf @davidsh if you have strong opinion on design and can present a good counter-argument, I will take this back to API review. |
Where are all of these extra parameters coming from? We're just asking for the parsing of a single string.
While I assume it's possible, I can't think of any situation where I've had a separate display name and email address but didn't already know the email address was valid. What we're looking for is to check a single column of values from a database or file feed. Usually as part of some sort of import job or data analysis. |
Also note we do have multi-parameter TryParse methods. For example, https://docs.microsoft.com/en-us/dotnet/api/system.datetime.tryparseexact?view=netframework-4.8 Other multi-parameter TryParse include So there is no basis for the claim that TryParse strictly has a single input parameter. |
The proposed API currently mirrors all the ctors, which take more than a single string.
This is not a claim anyone made. Current |
I'm working on this and I agree with @scalablecory if we want to return an "instance" of |
Triage: we like |
Yes @scalablecory feel free to assign to me. |
Currently we have to write this code:
MailAddress should have a TryParse method like Int32.TryParse.
Rationale and Usage
Throwing and catching exceptions can have a significant impact on performance. So when possible there should be a non-throwing alternative for methods that commonly fail. An example would be
Int32.Parse
andInt32.TryParse
.There is also an impact on debugger. If you have the IDE set to "Break on All Exceptions" in order to see where an exception is being thrown, it will also catch this even though it is not interesting.
Proposed API
Details
Open Questions
The text was updated successfully, but these errors were encountered: