Can I dynamically check a case statement of a switch in c#? - c#

Today I came across a problem: I was trying to check the errors of a software in order to provide the right behavior of the program when it incurs in the error.
I had to check if a user already exists in the database.
The problem is that the back-end doesn't provide an errorId so I have to check the errors by the text.
Errors are displayed as this:
The user Name already Exists!
The Switch statement is this:
switch (error.text)
{
case "User Test already exists":
Console.WriteLine("The user already Exists"); //this is a test behaviour.
break;
default:
Console.WriteLine("I couldn't behave in any way :<");
}
As you can imagine the names are all different (it's a unique field in the DB), so the word "Test" in the case statement should be the name of the user.
Can I dynamically change the string?

Seems like a Regex would do the trick. I've built this Regex based off the pattern:
The user Name already Exists!
where Name can be any value. The Regex is:
(the user .* already exists)
To use it you'll do something like this:
Regex.IsMatch(error.text, "(the user .* already exists)", RegexOptions.IgnoreCase)
Which would return a true or false based on the match. Now, this can't be done in the switch, but you could just run the value through a number of Regexes to determine which it matched. One thing you might consider is an extension method. Consider this one:
public static class RegexExtensions
{
private static readonly Regex UserNameAlreadyExists = new Regex("(the user .* already exists)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
public static bool IsUserNameAlreadyExists(this string inputValue)
{
return UserNameAlreadyExists.IsMatch(inputValue);
}
}
The usage for this would be really nice:
if (error.text.IsUserNameAlreadyExists())
{
// do something
}
The extension method is a really nice way of working through it. It's fully encapsulated and would keep the usage really clean. Furthermore, it's easier to define the Regex in one place and thus set it to Compiled making it faster.

Preferably change the back-end or have it changed (it definitely should return some sort of error code instead of an already localized message obviously meant to be shown to the user - that's clearly a front-end task).
To answer the question, no; consider using something like this instead (original phrasing, be aware that these string comparisons are case sensitive):
if(error.text.StartsWith("User ") && error.text.EndsWith(" already Exists"))
{
Console.WriteLine("The user already Exists"); //this is a test behaviour.
}
else
{
Console.WriteLine("I couldn't behave in any way :<");
}

I suppose this would be a fairly simple solution:
class Program
{
int errorIndex = 5; //Based on error expected text. Can add more criteria here.
private static bool testResponse = false;
static void Main(string[] args)
{
string text = "The user already exists";
getErrorMessage(text);
}
private static void getErrorMessage(string message)
{
var user = message.Substring(4, 4);
var exists = message.Substring(17, 6);
if (user == "user" && exists == "exists")
//Write the error message.
Console.WriteLine(message.ToString());
var errorMessage = message;
if (errorMessage != null)
{
testResponse = true;
}
Console.ReadLine();
}
}
This is if you know the exact location of the length and index of certain words of the error message. You could use that information to further narrow down the errors you expect. This is assuming that there is no errorId.

just to be sure: The back-end doesn't provide any errorID? If you use C# for the database connection (i.e. ADO.Net) you have possibilitys for efficent error handling.
Is it possible to just check if error.text is empty or not?
if(error.text=="")Console.WriteLine("The User already exists");
else Console.WriteLine("I couldn't behave in any way");
If you want to check if there are duplicates in the "user" column you could check the database directly via SQL.

Related

Method is only returning null. Searchs class list if user input equals what the user has inputed return the input else return null isn't working

as said in the title I have a class list on everytime that the program lauches it reads a txt file and the info the txt file gets changed into objects of that class (this works without a issue), but when I want to verify that what a user has input is equaled to something in this class list it doesn't seem to return the proper value but instead only every returns null. I can't seem to figure out why, I suppose I could maybe change the class list to a string list and verify via that way but kinda seems not the proper thing to do. I will provide code below. Some ideas would be helpful!
clientaccount is meant to be the input,
clientaccounts is the class list. If it doesn't contain it return null.
public Client? GetAccountAccountsE(ClientEmail cliEmail)
{
foreach (Client clientaccount in clientaccounts)
{
if (clientaccount.Equals(cliEmail)) { return clientaccount; Console.WriteLine("returning account"); }
}
Console.WriteLine("nulling");
return null;
}
You are comparing Client to ClientEmail, which are, unless you override the Equals()-method, not equal.
If ClientEmail email is a property of Client, try:
if (clientaccount.email.Equals(cliEmail)) {
Console.WriteLine("returning account");
return clientaccount;
}

how can I make sure that the user's answer is valid and if the answer isn't valid then ask the question again

I couldn't find the answer to this anywhere, so what I want to do is first, ask the user a question such as "do you want to see this cool movie?" and if the user replies yes then I show them the movie and if they reply no then I move on. If the user replied with something other than yes or no, such as "fadlfjlashfashdf", I wanted to be able to ask the user "Please answer yes or no." until they answer yes or no. The problem is, I couldn't find a way to do that without making the code very confusing and long. Here is something that I tried:
using System;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Do you want to see this cool move?");
string answer = Console.ReadLine();
while(answer.ToLower() != "yes" || answer.ToLower() != "no")
{
Console.WriteLine("Please type yes or no. ");
answer = Console.ReadLine();
}
if (answer.ToLower() == "yes")
{
Console.WriteLine("ok");
}
else if(answer.ToLower() == "no")
{
Console.WriteLine("sure");
}
}
}
You could use the TryXxx pattern made famous by calls like double.TryParse and Dictionar<TKey, TValue>.TryGetValue. First write a TryXxx method like:
static bool TryGetBooleanFromAnswerString(string answer, out bool isAffirmative)
{
if (answer.Equals("yes", StringComparison.OrdinalIgnoreCase))
{
isAffirmative = true;
return true;
}
if (answer.Equals("no", StringComparison.OrdinalIgnoreCase))
{
isAffirmative = false;
return true;
}
isAffirmative = false; //it's meaningless, but I need to set it to something
return false;
}
Notice that I used the string.Equals overload that takes a StringComparison parameter - it says that "Yes", "yes" and "YES" are all equivalent.
Then I can write code like:
bool answerAsBool;
do
{
Console.WriteLine(#"Wanna take a bath"); // I'm old enough to remember Pink Floyd
} while (!TryGetBooleanFromAnswerString(Console.ReadLine(), out answerAsBool));
Console.WriteLine($#"You answered with a {answerAsBool} answer");
Your approach here is perfectly reasonable. In fact, it's almost exactly how I'd do it.
In general, if there's some condition that needs to be handled in a special way (like invalid input), and it can happen multiples times in a row (the user continues to give invalid input), then you're gonna have to use a loop of some kind.
Now, with that said, there's a bug in your code. Can you find it?

How to modify this RegEx expression so it matches any characters followed by an # (just one) [duplicate]

What is the most elegant code to validate that a string is a valid email address?
What about this?
bool IsValidEmail(string email)
{
var trimmedEmail = email.Trim();
if (trimmedEmail.EndsWith(".")) {
return false; // suggested by #TK-421
}
try {
var addr = new System.Net.Mail.MailAddress(email);
return addr.Address == trimmedEmail;
}
catch {
return false;
}
}
Per Stuart's comment, this compares the final address with the original string instead of always returning true. MailAddress tries to parse a string with spaces into "Display Name" and "Address" portions, so the original version was returning false positives.
To clarify, the question is asking whether a particular string is a valid representation of an e-mail address, not whether an e-mail address is a valid destination to send a message. For that, the only real way is to send a message to confirm.
Note that e-mail addresses are more forgiving than you might first assume. These are all perfectly valid forms:
cog#wheel
"cogwheel the orange"#example.com
123#$.xyz
For most use cases, a false "invalid" is much worse for your users and future proofing than a false "valid". Here's an article that used to be the accepted answer to this question (that answer has since been deleted). It has a lot more detail and some other ideas of how to solve the problem.
Providing sanity checks is still a good idea for user experience. Assuming the e-mail address is valid, you could look for known top-level domains, check the domain for an MX record, check for spelling errors from common domain names (gmail.cmo), etc. Then present a warning giving the user a chance to say "yes, my mail server really does allow ๐ŸŒฎ๐Ÿณ๐ŸŽ as an email address."
As for using exception handling for business logic, I agree that is a thing to be avoided. But this is one of those cases where the convenience and clarity may outweigh the dogma.
Besides, if you do anything else with the e-mail address, it's probably going to involve turning it to a MailAddress. Even if you don't use this exact function, you will probably want to use the same pattern. You can also check for specific kinds of failure by catching different exceptions: null, empty, or invalid format.
--- Further reading ---
Documentation for System.Net.Mail.MailAddress
Explanation of what makes up a valid email address
This is an old question, but all the answers I've found on SO, including more recent ones, are answered similarly to this one. However, in .Net 4.5 / MVC 4 you can add email address validation to a form by adding the [EmailAddress] annotation from System.ComponentModel.DataAnnotations, so I was wondering why I couldn't just use the built-in functionality from .Net in general.
This seems to work, and seems to me to be fairly elegant:
using System.ComponentModel.DataAnnotations;
class ValidateSomeEmails
{
static void Main(string[] args)
{
var email = new EmailAddressAttribute();
email.IsValid("someone#somewhere.com"); //true
email.IsValid("someone#somewhere.co.uk"); //true
email.IsValid("someone+tag#somewhere.net"); //true
email.IsValid("futureTLD#somewhere.fooo"); //true
email.IsValid("fdsa"); //false
email.IsValid("fdsa#"); //false
email.IsValid("fdsa#fdsa"); //false
email.IsValid("fdsa#fdsa."); //false
//one-liner
if (new EmailAddressAttribute().IsValid("someone#somewhere.com"))
return true;
}
}
I use this single liner method which does the work for me-
using System.ComponentModel.DataAnnotations;
public bool IsValidEmail(string source)
{
return new EmailAddressAttribute().IsValid(source);
}
Per the comments, this will "fail" if the source (the email address) is null.
public static bool IsValidEmailAddress(this string address) => address != null && new EmailAddressAttribute().IsValid(address);
.net 4.5 added System.ComponentModel.DataAnnotations.EmailAddressAttribute
You can browse the EmailAddressAttribute's source, this is the Regex it uses internally:
const string pattern = #"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))#((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$";
I took Phil's answer from #1 and created this class.
Call it like this: bool isValid = Validator.EmailIsValid(emailString);
Here is the class:
using System.Text.RegularExpressions;
public static class Validator
{
static Regex ValidEmailRegex = CreateValidEmailRegex();
/// <summary>
/// Taken from http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx
/// </summary>
/// <returns></returns>
private static Regex CreateValidEmailRegex()
{
string validEmailPattern = #"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|"
+ #"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)"
+ #"#[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";
return new Regex(validEmailPattern, RegexOptions.IgnoreCase);
}
internal static bool EmailIsValid(string emailAddress)
{
bool isValid = ValidEmailRegex.IsMatch(emailAddress);
return isValid;
}
}
Personally, I would say that you should just make sure there is an # symbol in there, with possibly a . character. There's many regexes you could use of varying correctness, but I think most of these leave out valid email addresses, or let invalid ones through. If people want to put in a fake email address, they will put in a fake one. If you need to verify that the email address is legit, and that the person is in control of that email address, then you will need to send them an email with a special coded link so they can verify that it indeed is a real address.
Short and accurate code
string Email = txtEmail.Text;
if (Email.IsValidEmail())
{
//use code here
}
public static bool IsValidEmail(this string email)
{
string pattern = #"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|" + #"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)" + #"#[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";
var regex = new Regex(pattern, RegexOptions.IgnoreCase);
return regex.IsMatch(email);
}
I think the best way is as follow:
public static bool EmailIsValid(string email)
{
string expression = "\\w+([-+.']\\w+)*#\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
if (Regex.IsMatch(email, expression))
{
if (Regex.Replace(email, expression, string.Empty).Length == 0)
{
return true;
}
}
return false;
}
You can have this static function in a general class.
The most elegant way is to use .Net's built in methods.
These methods:
Are tried and tested. These methods are used in my own professional projects.
Use regular expressions internally, which are reliable and fast.
Made by Microsoft for C#. There's no need to reinvent the wheel.
Return a bool result. True means the email is valid.
For users of .Net 4.5 and greater
Add this Reference to your project:
System.ComponentModel.DataAnnotations
Now you can use the following code:
(new EmailAddressAttribute().IsValid("youremailhere#test.test"));
Example of use
Here are some methods to declare:
protected List<string> GetRecipients() // Gets recipients from TextBox named `TxtRecipients`
{
List<string> MethodResult = null;
try
{
List<string> Recipients = TxtRecipients.Text.Replace(",",";").Replace(" ", "").Split(';').ToList();
List<string> RecipientsCleaned = new List<string>();
foreach (string Recipient in RecipientsCleaned)
{
if (!String.IsNullOrWhiteSpace(Recipient))
{
RecipientsNoBlanks.Add(Recipient);
}
}
MethodResult = RecipientsNoBlanks;
}
catch//(Exception ex)
{
//ex.HandleException();
}
return MethodResult;
}
public static bool IsValidEmailAddresses(List<string> recipients)
{
List<string> InvalidAddresses = GetInvalidEmailAddresses(recipients);
return InvalidAddresses != null && InvalidAddresses.Count == 0;
}
public static List<string> GetInvalidEmailAddresses(List<string> recipients)
{
List<string> MethodResult = null;
try
{
List<string> InvalidEmailAddresses = new List<string>();
foreach (string Recipient in recipients)
{
if (!(new EmailAddressAttribute().IsValid(Recipient)) && !InvalidEmailAddresses.Contains(Recipient))
{
InvalidEmailAddresses.Add(Recipient);
}
}
MethodResult = InvalidEmailAddresses;
}
catch//(Exception ex)
{
//ex.HandleException();
}
return MethodResult;
}
...and code demonstrating them in action:
List<string> Recipients = GetRecipients();
bool IsValidEmailAddresses = IsValidEmailAddresses(Recipients);
if (IsValidEmailAddresses)
{
//Emails are valid. Your code here
}
else
{
StringBuilder sb = new StringBuilder();
sb.Append("The following addresses are invalid:");
List<string> InvalidEmails = GetInvalidEmailAddresses(Recipients);
foreach (string InvalidEmail in InvalidEmails)
{
sb.Append("\n" + InvalidEmail);
}
MessageBox.Show(sb.ToString());
}
In addition, this example:
Extends beyond the spec since a single string is used to contain 0, one or many email addresses sperated by a semi-colon ;.
Clearly demonstrates how to use the IsValid method of the EmailAddressAttribute object.
Alternative, for users of a version of .Net less than 4.5
For situations where .Net 4.5 is not available, I use the following solution:
Specifically, I use:
public static bool IsValidEmailAddress(string emailAddress)
{
bool MethodResult = false;
try
{
MailAddress m = new MailAddress(emailAddress);
MethodResult = m.Address == emailAddress;
}
catch //(Exception ex)
{
//ex.HandleException();
}
return MethodResult;
}
public static List<string> GetInvalidEmailAddresses(List<string> recipients)
{
List<string> MethodResult = null;
try
{
List<string> InvalidEmailAddresses = new List<string>();
foreach (string Recipient in recipients)
{
if (!IsValidEmail(Recipient) && !InvalidEmailAddresses.Contains(Recipient))
{
InvalidEmailAddresses.Add(Recipient);
}
}
MethodResult = InvalidEmailAddresses;
}
catch //(Exception ex)
{
//ex.HandleException();
}
return MethodResult;
}
To be honest, in production code, the best I do is check for an # symbol.
I'm never in a place to be completely validating emails. You know how I see if it was really valid? If it got sent. If it didn't, it's bad, if it did, life's good. That's all I need to know.
I find this regex to be a good trade off between checking for something more than just the # mark, and accepting weird edge cases:
^[^#\s]+#[^#\s]+(\.[^#\s]+)+$
It will at least make you put something around the # mark, and put at least a normal looking domain.
I just want to point out, that there has been a recent addition to the .NET documentation regarding email validation, also utilitzing Regex operations.
A thorough explanation to their implementation can be found there.
https://learn.microsoft.com/en-us/dotnet/standard/base-types/how-to-verify-that-strings-are-in-valid-email-format
For convenience, here is a list of their test results:
// Valid: david.jones#proseware.com
// Valid: d.j#server1.proseware.com
// Valid: jones#ms1.proseware.com
// Invalid: j.#server1.proseware.com
// Valid: j#proseware.com9
// Valid: js#internal#proseware.com
// Valid: j_9#[129.126.118.1]
// Invalid: j..s#proseware.com
// Invalid: js*#proseware.com
// Invalid: js#proseware..com
// Valid: js#proseware.com9
// Valid: j.s#server1.proseware.com
// Valid: "j\"s\""#proseware.com
// Valid: js#contoso.ไธญๅ›ฝ
I summarize all the above answers as of the current year 2021 I wrote for myself this class:
public static class StringExt {
private const string emailPattern = #"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|"
+ #"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)"
+ #"#[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";
public static bool IsValidMailAddress(this string pThis)
=> pThis is not null
&& Regex.IsMatch(pThis, emailPattern, RegexOptions.IgnoreCase);
}
Email address validation is not as easy as it might seem. It's actually theoretically impossible to fully validate an email address using just a regular expression.
Check out my blog post about it for a discussion on the subject and a F# implementation using FParsec. [/shameless_plug]
Here's my answer -- Phil's solution fails for single letter domains like "someone#q.com". Believe it or not, that's used =) (goes to centurylink, for instance).
Phil's answer is also going to work only with PCRE standard... so C# will take it, but javascript is going to bomb. It's too complex for javascript. So you can't use Phil's solution for mvc validation attributes.
Here's my regex. It'll work nicely with MVC validation attributes.
- Everything before the # is simplified, so that at least javascript will work. I'm okay relaxing validation here as long as exchange server doesn't give me a 5.1.3.
- Everything after the # is Phil's solution modified for single letter domains.
public const string EmailPattern =
#"^\s*[\w\-\+_']+(\.[\w\-\+_']+)*\#[A-Za-z0-9]([\w\.-]*[A-Za-z0-9])?\.[A-Za-z][A-Za-z\.]*[A-Za-z]$";
For people suggesting using system.net.mail MailMessage(), that thing is WAY to flexible. Sure, C# will accept the email, but then exchange server will bomb with 5.1.3 runtime error as soon as you try to send the email.
There are a lot of strong answers here. However, I recommend that we take a step back. #Cogwheel answers the question https://stackoverflow.com/a/1374644/388267. Nevertheless, it could be costly in a bulk validation scenario, if many of the email address being validated are invalid. I suggest that we employ a bit of logic before we enter into his try-catch block. I know that the following code could be written using RegEx but that could be costly for new developers to understand. This is my twopence worth:
public static bool IsEmail(this string input)
{
if (string.IsNullOrWhiteSpace(input)) return false;
// MUST CONTAIN ONE AND ONLY ONE #
var atCount = input.Count(c => c == '#');
if (atCount != 1) return false;
// MUST CONTAIN PERIOD
if (!input.Contains(".")) return false;
// # MUST OCCUR BEFORE LAST PERIOD
var indexOfAt = input.IndexOf("#", StringComparison.Ordinal);
var lastIndexOfPeriod = input.LastIndexOf(".", StringComparison.Ordinal);
var atBeforeLastPeriod = lastIndexOfPeriod > indexOfAt;
if (!atBeforeLastPeriod) return false;
// CODE FROM COGWHEEL'S ANSWER: https://stackoverflow.com/a/1374644/388267
try
{
var addr = new System.Net.Mail.MailAddress(input);
return addr.Address == input;
}
catch
{
return false;
}
}
As mentioned in many answers, the domain of email addresses is complex. I would strongly discourage the use of a regex in this case. Those who match (most) cases are extremely complex to read and therefor to maintain. Furthermore, the still have difficulties supporting all cases, and are slow.
Microsoft's EmailAddress class helps a bit in that respect, but is not perfect either, I would argue. For an open source project I gave it try some years ago, by using a customized EmailParser.
That is used in [EmailAddress]https://github.com/Qowaiv/Qowaiv/blob/master/src/Qowaiv/EmailAddress.cs).
By using this approach, you're not only to validate email addresses, but also by cleaning out multiple formats of display names, getting rid of the mailto:-prefix, and normalizing domain literals based on IP-addresses, and lowercasing everything (note that the local part officially is case sensitive).
Scenario's your solution should support (and the mentioned one does):
[TestCase(null)]
[TestCase("")]
[TestCase("..#test.com")]
[TestCase(".a#test.com")]
[TestCase("ab#sd#dd")]
[TestCase(".#s.dd")]
[TestCase("ab#988.120.150.10")]
[TestCase("ab#120.256.256.120")]
[TestCase("ab#120.25.1111.120")]
[TestCase("ab#[188.120.150.10")]
[TestCase("ab#188.120.150.10]")]
[TestCase("ab#[188.120.150.10].com")]
[TestCase("a#b.-de.cc")]
[TestCase("a#bde-.cc")]
[TestCase("a#bde.c-c")]
[TestCase("a#bde.cc.")]
[TestCase("ab#b+de.cc")]
[TestCase("a..b#bde.cc")]
[TestCase("_#bde.cc,")]
[TestCase("plainaddress")]
[TestCase("plain.address")]
[TestCase("#%^%#$##$##.com")]
[TestCase("#domain.com")]
[TestCase("Joe Smith <email#domain.com>")]
[TestCase("email.domain.com")]
[TestCase("email#domain#domain.com")]
[TestCase(".email#domain.com")]
[TestCase("email.#domain.com")]
[TestCase("email..email#domain.com")]
[TestCase("email#-domain.com")]
[TestCase("email#domain-.com")]
[TestCase("email#domain.com-")]
[TestCase("email#.domain.com")]
[TestCase("email#domain.com.")]
[TestCase("email#domain..com")]
[TestCase("email#111.222.333")]
[TestCase("email#111.222.333.256")]
[TestCase("email#[123.123.123.123")]
[TestCase("email#[123.123.123].123")]
[TestCase("email#123.123.123.123]")]
[TestCase("email#123.123.[123.123]")]
[TestCase("email#{leftbracket.com")]
[TestCase("email#rightbracket}.com")]
[TestCase("email#p|pe.com")]
[TestCase("isis#100%.nl")]
[TestCase("email#dollar$.com")]
[TestCase("email#r&d.com")]
[TestCase("email##hash.com")]
[TestCase("email#wave~tilde.com")]
[TestCase("email#exclamation!mark.com")]
[TestCase("email#question?mark.com")]
[TestCase("email#obelix*asterisk.com")]
[TestCase("email#grave`accent.com")]
[TestCase("email#colon:colon.com")]
[TestCase("email#caret^xor.com")]
[TestCase("email#=qowaiv.com")]
[TestCase("email#plus+.com")]
[TestCase("email#domain.com>")]
[TestCase("email( (nested) )#plus.com")]
[TestCase("email)mirror(#plus.com")]
[TestCase("email#plus.com (not closed comment")]
[TestCase("email(with # in comment)plus.com")]
[TestCase(#"""Joe Smith email#domain.com")]
[TestCase(#"""Joe Smith' email#domain.com")]
[TestCase(#"""Joe Smith""email#domain.com")]
[TestCase("email#mailto:domain.com")]
[TestCase("mailto:mailto:email#domain.com")]
[TestCase("Display Name <email#plus.com> (after name with display)")]
[TestCase("ReDoSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")]
public void IsInvalid(string email)
{
Assert.IsFalse(EmailAddress.IsValid(email), email);
}
[TestCase("w#com")]
[TestCase("w.b.f#test.com")]
[TestCase("w.b.f#test.museum")]
[TestCase("a.a#test.com")]
[TestCase("ab#288.120.150.10.com")]
[TestCase("ab#188.120.150.10")]
[TestCase("ab#1.0.0.10")]
[TestCase("ab#120.25.254.120")]
[TestCase("ab#01.120.150.1")]
[TestCase("ab#88.120.150.021")]
[TestCase("ab#88.120.150.01")]
[TestCase("ab#[120.254.254.120]")]
[TestCase("local#2001:0db8:85a3:0000:0000:8a2e:0370:7334")]
[TestCase("local#[2001:0db8:85a3:0000:0000:8a2e:0370:7334]")]
[TestCase("2#bde.cc")]
[TestCase("-#bde.cc")]
[TestCase("a2#bde.cc")]
[TestCase("a-b#bde.cc")]
[TestCase("ab#b-de.cc")]
[TestCase("a+b#bde.cc")]
[TestCase("f.f.f#bde.cc")]
[TestCase("ab_c#bde.cc")]
[TestCase("_-_#bde.cc")]
[TestCase("k.haak#12move.nl")]
[TestCase("K.HAAK#12MOVE.NL")]
[TestCase("email#domain.com")]
[TestCase("email#domain")]
[TestCase("ใ‚ใ„ใ†ใˆใŠ#domain.com")]
[TestCase("local#ใ‚ใ„ใ†ใˆใŠ.com")]
[TestCase("firstname.lastname#domain.com")]
[TestCase("email#subdomain.domain.com")]
[TestCase("firstname+lastname#domain.com")]
[TestCase("email#123.123.123.123")]
[TestCase("email#[123.123.123.123]")]
[TestCase("1234567890#domain.com")]
[TestCase("a#domain.com")]
[TestCase("a.b.c.d#domain.com")]
[TestCase("aap.123.noot.mies#domain.com")]
[TestCase("1#domain.com")]
[TestCase("email#domain-one.com")]
[TestCase("_______#domain.com")]
[TestCase("email#domain.topleveldomain")]
[TestCase("email#domain.co.jp")]
[TestCase("firstname-lastname#domain.com")]
[TestCase("firstname-lastname#d.com")]
[TestCase("FIRSTNAME-LASTNAME#d--n.com")]
[TestCase("first-name-last-name#d-a-n.com")]
[TestCase("{local{name{{with{#leftbracket.com")]
[TestCase("}local}name}}with{#rightbracket.com")]
[TestCase("|local||name|with|#pipe.com")]
[TestCase("%local%%name%with%#percentage.com")]
[TestCase("$local$$name$with$#dollar.com")]
[TestCase("&local&&name&with&$#amp.com")]
[TestCase("#local##name#with##hash.com")]
[TestCase("~local~~name~with~#tilde.com")]
[TestCase("!local!!name!with!#exclamation.com")]
[TestCase("?local??name?with?#question.com")]
[TestCase("*local**name*with*#asterisk.com")]
[TestCase("`local``name`with`#grave-accent.com")]
[TestCase("^local^^name^with^#xor.com")]
[TestCase("=local==name=with=#equality.com")]
[TestCase("+local++name+with+#equality.com")]
[TestCase("Joe Smith <email#domain.com>")]
[TestCase("email#domain.com (joe Smith)")]
[TestCase(#"""Joe Smith"" email#domain.com")]
[TestCase(#"""Joe\\tSmith"" email#domain.com")]
[TestCase(#"""Joe\""Smith"" email#domain.com")]
[TestCase(#"Test |<gaaf <email#domain.com>")]
[TestCase("MailTo:casesensitve#domain.com")]
[TestCase("mailto:email#domain.com")]
[TestCase("Joe Smith <mailto:email#domain.com>")]
[TestCase("Joe Smith <mailto:email(with comment)#domain.com>")]
[TestCase(#"""With extra < within quotes"" Display Name<email#domain.com>")]
[TestCase("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")]
public void IsValid(string email)
{
Assert.IsTrue(EmailAddress.IsValid(email), email);
}
If you really and I mean really want to know if an email address is valid...ask the mail exchanger to prove it, no regex needed. I can provide the code if requested.
General steps are as follows:
1. does email address have a domain name part? (index of # > 0)
2. using a DNS query ask if domain has a mail exchanger
3. open tcp connection to mail exchanger
4. using the smtp protocol, open a message to the server using the email address as the reciever
5. parse the server's response.
6. quit the message if you made it this far, everything is good.
This is as you can imagine, very expensive time wise and relies on smtp, but it does work.
a little modification to #Cogwheel answer
public static bool IsValidEmail(this string email)
{
// skip the exception & return early if possible
if (email.IndexOf("#") <= 0) return false;
try
{
var address = new MailAddress(email);
return address.Address == email;
}
catch
{
return false;
}
}
Generally speaking, a regular expression to validate email addresses is not an easy thing to come up with; at the time of this writing, the syntax of an email address must follow a relatively high number of standards and implementing all of them within a regular expression is practically unfeasible!
I highly suggest you to try our EmailVerify.NET, a mature .NET library which can validate email addresses following all of the current IETF standards (RFC 1123, RFC 2821, RFC 2822, RFC 3696, RFC 4291, RFC 5321 and RFC 5322), tests the related DNS records, checks if the target mailboxes can accept messages and can even tell if a given address is disposable or not.
Disclaimer: I am the lead developer for this component.
A simple one without using Regex (which I don't like for its poor readability):
bool IsValidEmail(string email)
{
string emailTrimed = email.Trim();
if (!string.IsNullOrEmpty(emailTrimed))
{
bool hasWhitespace = emailTrimed.Contains(" ");
int indexOfAtSign = emailTrimed.LastIndexOf('#');
if (indexOfAtSign > 0 && !hasWhitespace)
{
string afterAtSign = emailTrimed.Substring(indexOfAtSign + 1);
int indexOfDotAfterAtSign = afterAtSign.LastIndexOf('.');
if (indexOfDotAfterAtSign > 0 && afterAtSign.Substring(indexOfDotAfterAtSign).Length > 1)
return true;
}
}
return false;
}
Examples:
IsValidEmail("#b.com") // false
IsValidEmail("a#.com") // false
IsValidEmail("a#bcom") // false
IsValidEmail("a.b#com") // false
IsValidEmail("a#b.") // false
IsValidEmail("a b#c.com") // false
IsValidEmail("a#b c.com") // false
IsValidEmail("a#b.com") // true
IsValidEmail("a#b.c.com") // true
IsValidEmail("a+b#c.com") // true
IsValidEmail("a#123.45.67.89") // true
It is meant to be simple and therefore it doesn't deal with rare cases like emails with bracketed domains that contain spaces (typically allowed), emails with IPv6 addresses, etc.
For the simple email like goerge#xxx.com, below code is sufficient.
public static bool ValidateEmail(string email)
{
System.Text.RegularExpressions.Regex emailRegex = new System.Text.RegularExpressions.Regex(#"^([\w\.\-]+)#([\w\-]+)((\.(\w){2,3})+)$");
System.Text.RegularExpressions.Match emailMatch = emailRegex.Match(email);
return emailMatch.Success;
}
In case you are using FluentValidation you could write something as simple as this:
public cass User
{
public string Email { get; set; }
}
public class UserValidator : AbstractValidator<User>
{
public UserValidator()
{
RuleFor(x => x.Email).EmailAddress().WithMessage("The text entered is not a valid email address.");
}
}
// Validates an user.
var validationResult = new UserValidator().Validate(new User { Email = "aรงflkdj" });
// This will return false, since the user email is not valid.
bool userIsValid = validationResult.IsValid;
The most voted answer from #Cogwheel is best answer however i have tried to implement trim() string method so it will trim all user white space from string start to end. Check the code bellow for full example-
bool IsValidEmail(string email)
{
try
{
email = email.Trim();
var addr = new System.Net.Mail.MailAddress(email);
return addr.Address == email;
}
catch
{
return false;
}
}
Another Regex Match answer :
/// <summary>
/// Validates the email input
/// </summary>
internal static bool ValidateEmail(string _emailAddress)
{
string _regexPattern = #"^(([\w-]+\.)+[\w-]+|([a-zA-Z]{1}|[\w-]{2,}))#"
+ #"((([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\."
+ #"([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])){1}|"
+ #"([a-zA-Z]+[\w-]+\.)+[a-zA-Z]{2,4})$";
return (string.IsNullOrEmpty(_emailAddress) == false && System.Text.RegularExpressions.Regex.IsMatch(_emailAddress, _regexPattern))
? true
: false;
}
private static bool IsValidEmail(string emailAddress)
{
const string validEmailPattern = #"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|"
+ #"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)"
+ #"#[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";
return new Regex(validEmailPattern, RegexOptions.IgnoreCase).IsMatch(emailAddress);
}
Check email string is right format or wrong format by System.Text.RegularExpressions:
public static bool IsValidEmailId(string InputEmail)
{
Regex regex = new Regex(#"^([\w\.\-]+)#([\w\-]+)((\.(\w){2,3})+)$");
Match match = regex.Match(InputEmail);
if (match.Success)
return true;
else
return false;
}
protected void Email_TextChanged(object sender, EventArgs e)
{
String UserEmail = Email.Text;
if (IsValidEmailId(UserEmail))
{
Label4.Text = "This email is correct formate";
}
else
{
Label4.Text = "This email isn't correct formate";
}
}
/Using the Internal Regex used in creating the "new EmailAddressAttribute();" component in .Net4.5 >>> using System.ComponentModel.DataAnnotations;
//To Validate an Email Address......Tested and Working.
public bool IsEmail(string email)
{
if (String.IsNullOrEmpty(email))
{ return false; }
try
{
Regex _regex = new Regex("^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])" +
"+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)" +
"((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|" +
"[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\u" +
"FDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))#((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|" +
"(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|" +
"[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900" +
"-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFF" +
"EF])))\\.?$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled);
return _regex.IsMatch(email);
}
catch (RegexMatchTimeoutException)
{
return false;
}
}
Also, You can use this:
http://msdn.microsoft.com/en-us/library/01escwtf(v=vs.110).aspx
I succinctified Poyson 1's answer like so:
public static bool IsValidEmailAddress(string candidateEmailAddr)
{
string regexExpresion = "\\w+([-+.']\\w+)*#\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
return (Regex.IsMatch(candidateEmailAddr, regexExpresion)) &&
(Regex.Replace(candidateEmailAddr, regexExpresion, string.Empty).Length == 0);
}
Simple way to identify the emailid is valid or not.
public static bool EmailIsValid(string email)
{
return Regex.IsMatch(email, #"^([\w-\.]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
}

Optional in FormDialog

I'm using MS bot framework and FormDialog to ask the user to fill a form.
I would like some of the parameters to be optional and therefore added [Optional] indication to them:
[Prompt("Please specify if you have any additional requirements")]
[Optional]
string AdditionalRequirement { get; set; }
However, these questions still appear when the bot is filling up the form, and there is no way for the user to skip them (for instance just type "enter" or "skip")
Is there anything I'm doing wrong or is this the expected behavior? Is it possible to have a parameter that the user can skip in case it is not necessary?
update: seems the expected behaviour is that the optional parameters always show and there are certain words that can be understood as skipping the question, such as "No preference".
An answer that would explain how to add "skip" as one of the words to skip the question would be accepted.
I can think on two possible ways of achieving this (I couldn't test them, sorry!)
1) Decorate the optional field with a Template attribute, specifying the TemplateUsage.NoPreference usage as this.
[Template(TemplateUsage.NoPreference, "skip")]
2) Add the Skip term to the NoPreference array of the FormBuilder<T> configuration. Something like:
public static IFormBuilder<T> CreateCustomForm<T>()
where T : class
{
var form = new FormBuilder<T>();
var noPreferenceTerms = form.Configuration.NoPreference.ToList();
noPreferenceTerms.Add("skip");
form.Configuration.NoPreference = noPreferenceTerms.ToArray();
return form;
}
That then you can use like:
return CreateCustomForm<MyForm>()
As far as I know there isn't a way to add a Optional annotation to a field. What I know you can do is to pass a delegate to a method (or an anonymous method) where you can perform a check to see if the current field is active or not. If not, the field will not be prompted to the user. Heres a brief example:
public static IForm<MyForm> BuildForm()
{
return new FormBuilder<MyForm>()
.Field(nameof(AdditionalRequirement), active: IsAdditionalRequirementActive)
.Build();
}
private static bool IsAdditionalRequirementActive(MyForm state)
{
if (state.SomeOtherField == "Value")
return true;
else
return false;
}

CRM Plugin Error The given key was not present in the dictionary

I developed a CRM plugin that gets triggered when creating a Case entity. The Case has a N:1 relationship with another custom entity. Short story, when a field "new_CaseAssign" from the custom entity is set to 1, then the plugin will generate a Task assigned to Case Owner.
However the problem is that the field "new_CaseAssign" is newly added so most of the custom entity records don't have this field set yet, which causes the plugins to error out with "The given key was not present in the dictionary". If the custom field has value, then it's no problem.
What would be the best way to handle this situation? I tried customEntity.Attributes.Contains("new_CaseAssign") like below codes but no success:
var new_CaseAssign = customEntity.Attributes["new_CaseAssign"];
if ((customEntity.Attributes.Contains("new_CaseAssign")) && (bool)new_CaseAssign)
{
activityEntity.Attributes.Add("ownerid", incident.Attributes["ownerid"]);
}
else
{ //something else
}
Any suggestions is appreciated. Thanks much.
The line:
var new_CaseAssign = customEntity.Attributes["new_CaseAssign"];
is probably causing the exception. You could rewrite the code as:
bool new_CaseAssign = false;
if (customEntity.Attributes.Contains("new_CaseAssign"))
new_CaseAssign = (bool) customEntity.Attributes["new_CaseAssign"];
if (new_CaseAssign) {
activityEntity.Attributes.Add("ownerid", incident.Attributes["ownerid"]);
}
else { //something else
}
So first check contains before trying to access the key.
Loathing's answer is partially correct, in fact you are accessing the attribute before the check if is present or not. Normally I also check if the attribute it's not null before the cast.
The second error is with the field name, you are using late bound style, this means you need to use the logical name instead of the schema name, so the field name is new_caseassign (all lower case) instead of new_CaseAssign.
if ((customEntity.Attributes.Contains("new_caseassign")) && customEntity.Attributes["new_caseassign"] != null)
{
if ((bool)customEntity.Attributes["new_caseassign"])
{
activityEntity.Attributes.Add("ownerid", incident.Attributes["ownerid"]);
}
}
else
{ //something else
}

Categories