Validate that a given email address has a whitelisted domain and the address has not already been registered This is a remote validation method for a registration form, fired when the user enters an email address. It checks that the domain portion exists in a given list of valid domains, and then also checks the email address has not already been registered.

    [AllowAnonymous]
    [AcceptVerbs("Get", "Post")]
    public async Task&lt;JsonResult&gt; CheckEmail(string Email)
    {
        bool validDomain = false;
        string s = Email; //e.g. myname@my.org
        int idx = s.LastIndexOf('@');
        Console.WriteLine(s.Substring(0, idx)); //local half (not needed) e.g myname
        string domain = s.Substring(idx + 1).ToLower();    //domain half e.g. my.org

        IEnumerable&lt;Organisation&gt; organisations = _context.Organisations.ToList();

        foreach (var organisation in organisations)
        {
            if (domain == organisation.EmailDomain)
            {
                validDomain = true;
                break;
            }
        }

        if (validDomain == false)
        {
            return Json(
                data: "" + domain + " accounts cannot be used");
        }

        var result = await _userManager.FindByEmailAsync(Email);
        if (result == null)
        {
            return Json(data: true);
        }
        return Json(data: $"Email address already registered&lt;/a&gt;");

    }


I also tried to use this line instead of the foreach loop but wouldn't get it to work:


//string result = organisations.FirstOrDefault(o =&gt; o.Contains(domain));



I got "symbol Contains cannot be resolved."

Would appreciate feedback on improving the rest of the code if possible.
There are a few things that jump out at me in your code:

public async Task&lt;JsonResult&gt; CheckEmail(string Email)


Email should be email because it is conventional for parameters to be camelCase in C#.



Why are you making a copy of the email address?

string s = Email;


Strings are immutable, you can just use your parameter directly.



This line:

Console.WriteLine(s.Substring(0, idx)); //local half (not needed) e.g myname


First, you should never be using Console.WriteLine in a action method of a controller. Generally, you shouldn't be using it in a web app at all. If you want to debug it, add a log or just step through with an actual debugger using breakpoints.

Second, if you don't need the local half, why do you compute it at all?

Third, you haven't validated that the email address even contains an @. If it doesn't, this line will throw an exception.

Validate your index:

var atCharPosition = email.LastIndexOf('@');
if (atCharPosition == -1) 
{
   return Json(data: "Invalid email address");
}




This line is the most worrying:

IEnumerable&lt;Organisation&gt; organisations =  _context.Organisations.ToList();


Is that _context an Entity Framework Data Context? If it is, you're getting all of the organisations back from the database to see whether the domain exists. Let the database do it:

// requires a using System.Linq;
var isValidDomain =  _context.Organisations.Any(o =&gt; o.EmailDomain == domain);




Finally, why are you returning a closing anchor tag in this line?

return Json(data: $"Email address already registered&lt;/a&gt;");


I can't see any reason why you'd want to return malformed html here.