I have the following method:
public async Task<IActionResult> GetUsersAPICall([Bind(nameof(query))] [RegularExpression(@"^\w+(\.\w+)*@\w+(\.\w+)+|(\w+(\s\w+)*)|[a-z0-9]+$", ErrorMessage = "This does not look like a valid query")] string query)
{
if (!ModelState.IsValid)
{
return BadRequest();
}
}
This fails for email addresses like test-def.ghi@de.jkl.com
(but not for email addresses like test@test.com
).
I know for a fact that the regex is the correct pattern, because the following LINQPad script displays True
as expected for the exact same email address:
void Main()
{
var r = new Regex(@"^\w+(\.\w+)*@\w+(\.\w+)+|(\w+(\s\w+)*)|[a-z0-9]+$");
r.IsMatch("test-def.ghi@de.jkl.com").Dump();
}
I tried dropping the [Bind(nameof(query))]
entirely, but that didn't help.
If I change this to
public async Task<IActionResult> GetUsersAPICall([Bind(nameof(query))] string query)
{
if (!Regex.IsMatch(query, @"^\w+(\.\w+)*@\w+(\.\w+)+|(\w+(\s\w+)*)|[a-z0-9]+$"))
{
return BadRequest();
}
// ...
}
I'm completely baffled as to why what I had originally wasn't working. Can someone see what I'm missing here?
The closest I've found so far on Stack Overflow is this Q&A, but there it turned out that the OP's regex was wrong (which isn't the case for me, since the Regex works just fine in two different contexts).
Problem is within your regex and difference in its handling by IsMatch
and RegularExpression
annotation.
IsMatch
checks if input contains anything matching provided regex.
Documentation:
Indicates whether the specified regular expression finds a match in the specified input string, using the specified matching options and time-out interval.
So it's trying to find any match in your input, finds it (specifically for second alteration: (\w+(\s\w+)*)
) and returns true.
RegularExpression
annotation on the other hand checks if your whole input matches provided regex. Documentation:
The regular expression searches for an exact match, not using
^
before and$
at the end of the pattern produces the same results as using it. For a search hit, prepend and append the pattern with.*
.
So effectively, annotation applies pattern ^(?:^\w+(\.\w+)*@\w+(\.\w+)+|(\w+(\s\w+)*)|[a-z0-9]+$)$
.
Probably you tried to achieve similar effect, but forgot parenthesis?