Is there any way to make a textbox input validation for email addresses in wpf C#? Regex or validation expression or anything that can help, best with code sample and some instructions
On the text_changed event you could pass the value of the textbox to a helper class.
public static class ValidatorExtensions
{
public static bool IsValidEmailAddress(this string s)
{
Regex regex = new Regex(#"^[\w-\.]+#([\w-]+\.)+[\w-]{2,4}$");
return regex.IsMatch(s);
}
}
Now on the text changed event you can test the input
private void myTextBox_TextChanged(object sender, EventArgs e)
{
bool result = ValidatorExtensions.IsValidEmailAddress( myTextBox.Text );
}
There are several ways to check if the email address is valid
About System.Net.Mail.MailAddress
About Regex Expression
static void Main(string[] args)
{
var validMail = "validMail#gmail.com";
var invalidMail = "123";
Console.WriteLine("IsValidMailAddress1 Test");
Console.WriteLine(string.Format("Mail Address : {0} . is valid : {1}", validMail, IsValidMailAddress1(validMail)));
Console.WriteLine(string.Format("Mail Address : {0} . is valid : {1}", invalidMail, IsValidMailAddress1(invalidMail)));
Console.WriteLine("IsValidMailAddress2 Test");
Console.WriteLine(string.Format("Mail Address : {0} . is valid : {1}", validMail, IsValidMailAddress2(validMail)));
Console.WriteLine(string.Format("Mail Address : {0} . is valid : {1}", invalidMail, IsValidMailAddress2(invalidMail)));
}
static bool IsValidMailAddress1(string mail)
{
try
{
System.Net.Mail.MailAddress mailAddress = new System.Net.Mail.MailAddress(mail);
return true;
}
catch
{
return false;
}
}
static bool IsValidMailAddress2(string mailAddress)
{
return Regex.IsMatch(mailAddress, #"^([\w\.\-]+)#([\w\-]+)((\.(\w){2,3})+)$");
}
This is the best one I found:
Regex.IsMatch(emailAddress, #"\A(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\Z", RegexOptions.IgnoreCase)
Actually, a great number of things have to be considered when validating email addresses:
Nearly all Regex expressions found on the Internet are not 100%
correct
Even if the Regex is doing a 100% perfect job, the email client like
Outlook or email server like Exchange might not accept the exotic,
but valid email address.
Just one example of a strange, but valid email address:
"very.(),:;<>[]\".VERY.\"very#\ \"very\".unusual"#strange.example.com
which is of the type:
John.Doe#example.com
But actually, RFC 5322: Internet Message Format: Address Specification specifies that en email address looks like this:
John Doe<John.Doe#example.com>
The first "John Doe" is the display name.
If you add display name validation, it becomes rather complicated. But even without display name, most regex fail to recognise the following email address as valid:
"John#Doe"#example.com
Therefore the recommendation is just to warn the user if an email address looks strange, but to let the user decide if he made a typo or if he actually wants to enter that email address.
Additionally to validation, it might be helpful when the user can key in only legal characters.
Read my article CodeProject: Email Address Validation Explained, it comes with the code of a fully implemented and tested WPF Email Textbox.
Related
Hi I am working on a bulk email sending feature. Below is my loop that validates email and sends them to each recipient:
foreach (var userID in recipientUserIds)
{
var userInfo = //getting from database using userID.
try
{
to = new MailAddress(userInfo.Email1, userInfo.FirstName + " " + userInfo.LastName);
}
catch (System.FormatException fe)
{
continue;
}
using (MailMessage message = new MailMessage(from, to))
{
//populate message and send email.
}
}
Since the recipientUserIds is always more than 2000, using try-catch seems to be very expensive for each user in this case just to validate the email address format. I was wondering to use regex, but not sure if that will help with performance.
So my question is if there is any better or performance optimized way to do the same validation.
Validating email addresses is a complicated task, and writing code to do all the validation up front would be pretty tricky. If you check the Remarks section of the MailAddress class documentation, you'll see that there are lots of strings that are considered a valid email address (including comments, bracketed domain names, and embedded quotes).
And since the source code is available, check out the ParseAddress method here, and you'll get an idea of the code you'd have to write to validate an email address yourself. It's a shame there's no public TryParse method we could use to avoid the exception being thrown.
So it's probably best to just do some simple validation first - ensure that it contains the minimum requirements for an email address (which literally appears to be user#domain, where domain does not have to contain a '.' character), and then let the exception handling take care of the rest:
foreach (var userID in recipientUserIds)
{
var userInfo = GetUserInfo(userID);
// Basic validation on length
var email = userInfo?.Email1?.Trim();
if (string.IsNullOrEmpty(email) || email.Length < 3) continue;
// Basic validation on '#' character position
var atIndex = email.IndexOf('#');
if (atIndex < 1 || atIndex == email.Length - 1) continue;
// Let try/catch handle the rest, because email addresses are complicated
MailAddress to;
try
{
to = new MailAddress(email, $"{userInfo.FirstName} {userInfo.LastName}");
}
catch (FormatException)
{
continue;
}
using (MailMessage message = new MailMessage(from, to))
{
// populate message and send email here
}
}
I'm using System.Net.Mail to send email in my application but I get an exception and I can't figure out what/where the problem is and how to fix it.
The error says I have some invalid char:
An invalid character was found in the mail header: ';'.
I tried google without success.
The string with email address is:
john#mydomain.org; beth#mydomain.org; alfred#mydomain.org; barbie#mydomain.org;
Here is my email sending code:
SmtpClient smtpClient = new SmtpClient("smtp.........");
System.Net.Mail.MailMessage mailMessagePlainText = new System.Net.Mail.MailMessage();
mailMessagePlainText.IsBodyHtml = true;
mailMessagePlainText.From = new MailAddress("vincent#mydomain.org", "admin");
mailMessagePlainText.Subject = "test";
mailMessagePlainText.Body = "test";
mailMessagePlainText.To.Add(new MailAddress(List1.ToString(), ""));
mailMessagePlainText.Bcc.Add(new MailAddress("vincent#mydomain.org", ""));
try
{
smtpClient.Send(mailMessagePlainText);
}
catch (Exception ex)
{
throw (ex);
}
foreach (var address in List1.split(';')) {
mailMessagePlainText.To.Add(new MailAddress(address.Trim(), ""));
}
Because according to your string here above, each address in this loop above would produce following:
"john#mydomain.org"
" beth#mydomain.org"
" alfred#mydomain.org"
" barbie#mydomain.org"
So by adding .Trim() to address would make your code work.
A MailAddressCollection (like your mailMessagePlainText.To) has an Add method that accepts a string containing a list of mail addresses, separated by a comma.
So to use that, you will need to change the ; into a , and possibly remove the extra spaces.
It looks like you're adding the addresses as a single MailAddress, where you need to add them 1 at a time. I don't know what other overloads are available, but the following will probably work.
I split the string by ; and add each address separately.
replace
mailMessagePlainText.To.Add(new MailAddress(List1.ToString(), ""));
with
foreach (var address in List1.split(';')) {
mailMessagePlainText.To.Add(new MailAddress(address , ""));
}
I am writing a very data intensive Metro App where I need to send an email in html format. After googling around I came across this code.
var mailto = new Uri("mailto:?to=recipient#example.com&subject=The subject of an email&body=Hello from a Windows 8 Metro app.");
await Windows.System.Launcher.LaunchUriAsync(mailto);
This works great for me with one exception. I am generating the body of this email via html string so I have code in my class like this.
string htmlString=""
DALClient client = new DALClient();
htmlString += "<html><body>";
htmlString += "<table>";
List<People> people = client.getPeopleWithReservations();
foreach(People ppl in people)
{
htmlString+="<tr>"
htmlString +="<td>" + ppl.PersonName + "</td>";
htmlString +="</tr>";
}
htmlString +="</table>";
htmlString +="</body><html>";
Now when I run this code the email client opens up. However the result appears as plain text. Is there a way I can have this show up in the formatted html so the html tags and so forth wont display?
Thanks in advance.
It is just not possible to pass HTML to mailto. You could use sharing instead where you can pass HTML code to the default Windows Store Mail App (unfortunately not to the default Desktop Mail Application).
Here is a sample on a page:
public sealed partial class MainPage : Page
{
private string eMailSubject;
private string eMailHtmlText;
...
private void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
// Check if an email is there for sharing
if (String.IsNullOrEmpty(this.eMailHtmlText) == false)
{
// Pass the current subject
args.Request.Data.Properties.Title = this.eMailSubject;
// Pass the current email text
args.Request.Data.SetHtmlFormat(
HtmlFormatHelper.CreateHtmlFormat(this.eMailHtmlText));
// Delete the current subject and text to avoid multiple sharing
this.eMailSubject = null;
this.eMailHtmlText = null;
}
else
{
// Pass a text that reports nothing currently exists for sharing
args.Request.FailWithDisplayText("Currently there is no email for sharing");
}
}
...
// "Send" an email
this.eMailSubject = "Test";
this.eMailHtmlText = "Hey,<br/><br/> " +
"This is just a <b>test</b>.";
DataTransferManager.ShowShareUI();
Another approach would be to use SMTP but as far as I know there is no SMTP implementation yet for Windows Store Apps.
I have read on SO about validating emails with MailAddress and have produced the folowing code:
try
{
var address = new MailAddress(value.Email);
}
catch (FormatException)
{
emailError = "Invalid Email";
}
To my great surprise the string ndskfndlfk#sdflsdf validates as good email.
Any idea why is it so?
If you really need to filter those email addresses, you could use the little utility found here, which uses Regex to validate email addresses. Note that this is the .Net 4.0 version - it's a little different for 4.5.
using System;
using System.Globalization;
using System.Text.RegularExpressions;
public class RegexUtilities
{
bool invalid = false;
public bool IsValidEmail(string strIn)
{
invalid = false;
if (String.IsNullOrEmpty(strIn))
return false;
// Use IdnMapping class to convert Unicode domain names.
strIn = Regex.Replace(strIn, #"(#)(.+)$", this.DomainMapper);
if (invalid)
return false;
// Return true if strIn is in valid e-mail format.
return Regex.IsMatch(strIn,
#"^(?("")(""[^""]+?""#)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])#))" +
#"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9]{2,17}))$",
RegexOptions.IgnoreCase);
}
private string DomainMapper(Match match)
{
// IdnMapping class with default property values.
IdnMapping idn = new IdnMapping();
string domainName = match.Groups[2].Value;
try {
domainName = idn.GetAscii(domainName);
}
catch (ArgumentException) {
invalid = true;
}
return match.Groups[1].Value + domainName;
}
}
Otherwise, if it's for user registration, I usually just depend on email verification - i.e. the system sends the user an email with a link, and clicking the link therefore validates that the email address is real.
It is possible for a valid email address not to be a real one. In other words, it may even pass a perfect validation system, but that's no guarantee that it exists.
That might not be valid WWW domain name but on a private network I think it is a valid domain name. If you want to get more selective then Regex.
I try and parse legit email (eliminate phony used by spam) using Regex and it is messy.
If you have access to the actual email header then it does not really get easier but it get more accurate.
I am trying to parse out IP addresses from Outlook email headers. I've started writing some stuff in C# (because that is the example I was leveraging) and have come up with something close.
I can split the headers with the string lines[] = Regex.Split(headers, #"\r\n"); command okay, but when I try to iterate through the lines[] array, my regex for IP address fails and does not store the value in a second array:
Code:
private void button1_Click(object sender, EventArgs e)
{
// use a string constant to define the mapi property
string PidTagTransportMessageHeaders = #"http://schemas.microsoft.com/mapi/proptag/0x007D001E";
string mypattern = #"(#{1,3}\.)(#{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3})";
// string[] ip = Regex.Split(lines[i], (#"(\(|\[)(#{1,3}\.)(#{1,3}\.)([0-9]{1,3}\.)([0-9]{1,3})(\)|\])"));
// get a handle on the current message
Outlook.MailItem message = (Outlook.MailItem)this.OutlookItem;
// use the property accessor to retreive the header
string headers = string.Empty;
try
{
headers = (string)message.PropertyAccessor.GetProperty(PidTagTransportMessageHeaders);
}
catch {
}
// if getting the internet headers is successful, put into textbox
string[] lines = Regex.Split(headers, "\r\n");
Regex regexObj = new Regex(mypattern);
for (int i = 0; i < lines.Length; i++)
{
MatchCollection matches = regexObj.Matches(lines[i]);
}
//eventually write the found IP array into textBox1.Text
textBox1.Text = headers;
}
}
}
Any help or suggestions?
Change your #'s to \d's:
string mypattern = #"(\d{1,3}\.)(\d{1,3}\.)(\d{1,3}\.)(\d{1,3})";
Note that a more accurate IPv4 address capture regular expression would be something like:
\b(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\b
...or at least add word boundaries...
\b(\d{1,3}\.)(\d{1,3}\.)(\d{1,3}\.)(\d{1,3})\b
For a simple IPv6 (standard) I like:
(?<![:.\w])(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}(?![:.\w])
IPAddress.Parse Method do not reinvent the wheel.
If you're trying to match off IPv4, then try this beast, should be fairly close to what an actual IPv4 can be, the enclosing \b mean beginning and end of a word, so you should be able to remove those and tweak to your heart's content to get the ip based on your header format
\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b