I am new to c# and Ive come across something I can't fix.
situation
I am creating a windows form application using visual studio 2010 which has the option to validate an email address. I looked at tutorials on using RegularExpressions and have came to this. I feel I'm missing something because every time I validate, it only sends the MessageBox.Show("Email invalid"); to the user.
code
private void validateBtn_Click(object sender, EventArgs e)
{
Regex email = new Regex("^[a-zA-Z0-9]{1-20}#[a-zA-Z0-9]{1-20}.[a-zA-Z]{2-3}$");
if (!email.IsMatch(emailTxt.Text))
{
MessageBox.Show("Email invalid");
}
else
MessageBox.Show("Email Valid");
}
Normally I would never use an Exception to direct program logic like this, but when validating emails I've found using built-in .NET functionality to be more reliable and readable than trying to use Regex to validate an email address.
using (var mm = new MailMessage())
{
try
{
mm.To.Add(emailTxt.Text);
MessageBox.Show("Email Valid");
... rest of your code to send the email
}
catch (FormatException)
{
MessageBox.Show("Email Invalid");
}
}
Alternatively, to just test the address:
try
{
var mail = new MailAddress(emailTxt.Text);
MessageBox.Show("Email Valid");
}
catch (FormatException)
{
MessageBox.Show("Email Invalid");
}
This class is not perfect, and you can find posts showing it doesn't catch every edge case.
But when this is the alternative, I think I'd rather stick with the above and take my chances.
. is a special character, use
Regex email = new Regex(#"^[a-zA-Z0-9]{1-20}#[a-zA-Z0-9]{1-20}\.[a-zA-Z]{2-3}$");
please note I added a '#' in front of the string to avoid escaping the '\'
You have two syntax errors in your regex:
. stands for a random sign, so it must be escaped with a backslash: \. .
{1-20} musst be written with comma: {1,20}.
[a-zA-Z0-9]{1,20}#[a-zA-Z0-9]{1,20}\.[a-zA-Z]{2,3}
works.
if you use C# you have to bring a # before the first " to say it that it should not use backslashes in the string to escape. It should do this when searching for regex.
#"[a-zA-Z0-9]{1,20}#[a-zA-Z0-9]{1,20}\.[a-zA-Z]{2,3} "
Related
I have a C# backend code that receives a POST request from the client side code in TypeScript.
The JSON is done for the POST with JSON.stringify(objectOfData);
In the C# code I am getting an exception when I try to use the object like so:
// Passed into this function is InboundObjectDTO inboundObject
// inboundObject.Email in debugger is like so: "\"a#example.com\""
var message = new MailMessageDTO
{
Subject = "My Subject",
MailAddresses = new List<MailAddress>()
};
message.MailAddresses.Add(new MailAddress(inboundObject.Email));
Am I supposed to deserialize the object somehow before hand? I have 3 strings in the object: email, message, and name.
The last line of code above gives me "An invalid character in MailAddresses exception." I am guessing it needs to have all the extra quotes and such removed in a proper way.
As OP had originally postulated, the issue is the quotes around the email address, all we need to do is remove those quotes. This process is referred to as Sanitizing the input.
The original methodology was hard to follow and the exception information posted was ambiguous, this solution shows how to sanitise the input and return more relevant information with the exception.
The example you have pasted ""a#example.com"" would not fail in your original code that included the santize logic, if you had simply used the result of the sanitize step!
You should wrap the code block in a try-catch so you can capture the exception and output the specific string value that has failed:
string email = inboundObject.Email;
MailMessageDTO message = null;
try
{
// sanitized the email, removed known invalid characters
email = email.Replace("\"", "");
// construct the payload object
message = new MailMessageDTO
{
Subject = "My Subject",
MailAddresses = new List<MailAddress>()
};
message.MailAddresses.Add(new MailAddress(email));
}
catch (Exception ex)
{
throw new ApplicationException($"Failed to construct MailMessage for email: {email}", ex);
}
Now when this fails, we have more information to work with inside the exception, infact this situation itself probably warrants it's own separate reusable method:
public MailAddress SanitizeEmail(string emailAddress)
{
string email = emailAddress;
try
{
// sanitized the email, removed known invalid characters
email = email.Replace("\"", "");
// TODO: add other rules an replacement cases as you find them
return new MailAddress(email);
}
catch (Exception ex)
{
throw new ApplicationException($"Failed to sanitize email address: '{email}' [original input: '{emailAddress ?? "NULL" }']", ex);
}
}
You could call this using:
message.MailAddresses.Add(SanitizeEmail(email));
Update
OP's original code included references and test conditions that are no longer in the posted code, this response has only been marginally updated to reflect those changes
If you are posting json data to controller action,you can use [FromBody],[FromBody] will get values from the request body:
public IActionResult Index([FromBody]inboundObject inboundObject)
{
...
}
Or you can use JsonConvert.DeserializeObject to deserialize the the JSON to specified .NET type:
message.MailAddresses.Add(new MailAddress(JsonConvert.DeserializeObject<string>(inboundObject.Email)));
I'm managing forwarded e-mails and noting that if I perform a TextSearchQuery(SearchTerm.FromContains, "test#test.com") I just get the UniqueIds of the forwarder, not the original sender of the e-mail.
I know I could dive into the TextBody or the HtmlBody and look at the "from", but this could vary depending on the language of the client and so on, so I was wondering if is there any method to perform that "deep SearchQuery".
There are so many SearchTerm but a SearchTerm.OriginalFromContains could be interesting, if it doesn't exists yet!
Thanks.
It's not a fire-proof solution but I actually search for all the "mailTo"s on the e-mail, I list them and I give the user the option to exclude a concrete domain of the list.
I finally pick up the last mailTo.
private string ExtractMailTo(string html, string domainToExclude)
{
try
{ //Searches for mailTos with regEx
//If user didn't pass any domain we will just ignore it
//and pick up the last mailTo.
bool deleteDomainUser = (!string.IsNullOrEmpty(domainToExclude)
|| !string.IsNullOrWhiteSpace(domainToExclude));
var mailTos = new List<String>();
string pattern = #"mailto\s*:\s*([^""'>]*)";
foreach (Match match in Regex.Matches(html, pattern))
mailTos.Add(match.Groups[1].Value);
if(deleteDomainUser)
//We search for the domain concreted by the user
//and we delete it from the mailTos List
mailTos.RemoveAll(doms => doms.Contains(domainToExclude));
var last = mailTos.Last();
return last;
}
catch (Exception ex)
{
string message = "A problem ocurred parsing the e-mail body searching for MailTos. \n"
+ ex.Message;
throw new Exception(message, ex);
}
}
Hope it helps somebody.
There's no way to do what you want as IMAP does not support it. MailKit's search API's are limited to the search capabilities of the IMAP protocol (which, unfortunately, are rather limited).
Previous answers are ok, but none of them will give us senders. Same as #Gonzo345 in last answer we can find emails in message.HtmlBody. My solution:
string afterFromPattern = #"From:.*(\n|\r|\r\n)";
string emailPattern = #"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?";
foreach (Match match in Regex.Matches(message.HtmlBody, afterFromPattern))
{
fromEmail = Regex.Match(match.Value, emailPattern).Value.ToLower();
if (string.IsNullOrEmpty(fromEmail))
{
continue;
}
fromEmails.Add(fromEmail);
}
so after searching both on here and Google I have been unable to find a solution. Basically I want to allow the user to add a list of proxies from a text file, but I want to check that what gets passed in is a valid Proxy format before I make the WebProxy. I know using try catch like try {var proxy = new WebProxy(host + ":" + port;} catch{} will work, but as you may already know using try catch is slow, even more so when doing it in bulk.
So what would be a good and fast way to test a string to see if it's in a valid WebProxy format?
Thanks
This is how I do it:
var ValidIpAddressPortRegex = #"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):[\d]+$";
if (System.Text.RegularExpressions.Regex.IsMatch(proxy_string_to_validate, ValidIpAddressPortRegex ))
{
do_stuff_with_proxy();
}
else
{
//MessageBox.Show("IP:PORT url not valid!","Information");
}
I am trying to validate if the userinput is an email adress (adding a member to database).
The user will enter data in TextBox, when the validating event gets called; I want to check if the input is a valid email adress. So consisting of atleast an # and a dot(.) in the string.
Is there any way to do this through code, or perhaps with a Mask from the MaskedTextbox?
Don't bother with Regex. It's a Bad Idea.
I normally never use exceptions to control flow in the program, but personally, in this instance, I prefer to let the experts who created the MailAddress class do the work for me:
try
{
var test = new MailAddress("");
}
catch (FormatException ex)
{
// wrong format for email
}
Do not use a regular expression, it misses so many cases it's not even funny, and besides smarter people that us have come before to solve this problem.
using System.ComponentModel.DataAnnotations;
public class TestModel{
[EmailAddress]
public string Email { get; set; }
}
Regex for simple email match:
#"\b[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}\b"
Regex for RFC 2822 standard email match:
#"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?"
See: How to: Verify that Strings Are in Valid Email Format - MSDN
The Regex you are looking should be:
"^(?("")(""[^""]+?""#)|(([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,24}))$"
(From the same source)
I recommend you use this way and it's working well for me.
Regex reg = new Regex(#"\w+([-+.]\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*");
if (!reg.IsMatch(txtEmail.Text))
{
// Email is not valid
}
I suggest that you use a Regular Expression like:
#"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?"
To validate the input of your textbox.
Example code:
private void button1_Click(object sender, EventArgs e)
{
Regex emailRegex = new Regex(#"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?
^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+
[a-z0-9](?:[a-z0-9-]*[a-z0-9])?");
if (emailRegex.IsMatch(textBox1.Text))
{
MessageBox.Show(textBox1.Text + "matches the expected format.", "Attention");
}
}
Edit: I found a better, more comprehensive Regex.
I need to validate a folder name in c#.
I have tried the following regex :
^(.*?/|.*?\\)?([^\./|^\.\\]+)(?:\.([^\\]*)|)$
but it fails and I also tried using GetInvalidPathChars().
It fails when i try using P:\abc as a folder name i.e Driveletter:\foldername
Can anyone suggest why?
You could do that in this way (using System.IO.Path.InvalidPathChars constant):
bool IsValidFilename(string testName)
{
Regex containsABadCharacter = new Regex("[" + Regex.Escape(System.IO.Path.InvalidPathChars) + "]");
if (containsABadCharacter.IsMatch(testName) { return false; };
// other checks for UNC, drive-path format, etc
return true;
}
[edit]
If you want a regular expression that validates a folder path, then you could use this one:
Regex regex = new Regex("^([a-zA-Z]:)?(\\\\[^<>:\"/\\\\|?*]+)+\\\\?$");
[edit 2]
I've remembered one tricky thing that lets you check if the path is correct:
var invalidPathChars = Path.GetInvalidPathChars(path)
or (for files):
var invalidFileNameChars = Path.GetInvalidFileNameChars(fileName)
Validating a folder name correctly can be quite a mission. See my blog post Taking data binding, validation and MVVM to the next level - part 2.
Don't be fooled by the title, it's about validating file system paths, and it illustrates some of the complexities involved in using the methods provided in the .Net framework. While you may want to use a regex, it isn't the most reliable way to do the job.
this is regex you should use :
Regex regex = new Regex("^([a-zA-Z0-9][^*/><?\"|:]*)$");
if (!regex.IsMatch(txtFolderName.Text))
{
MessageBox.Show(this, "Folder fail", "info", MessageBoxButtons.OK, MessageBoxIcon.Information);
metrotxtFolderName.Focus();
}