0

I have email field on an asp.net mvc form. I need to verify the email using remote validation by calling a net core api server. Remote validation is activated when the email field looses focus. However, the call to api server stalled at async call to api method.

    public class Model
    {
    [Required]
    [StringLength(50, ErrorMessage = "The {0} exceeds {1} characters")]
    [EmailAddress(ErrorMessage = "Invalid Email Address")] // NOTE:  This attribute REQUIRES .Net 4.5 or higher!
    [DataType(DataType.EmailAddress)]
    [Display(Name = "Email", ResourceType = typeof(Resources.Resources))]
    [Remote(action: "VerifyEmail", controller: "Account")]
    public string Email { get; set; }
    }

public class AccountController : Controller
{
    CoreApiHelp _apiHelper = new ApiHelp();
    public AccountController()
    {

    }
    [AllowAnonymous]
    [AcceptVerbs("Get", "Post")]
    public ActionResult VerifyEmail(string email)
    {
        if (!_apiHelper.VerifyEmail(email).Result)
        { 
            return Json($"Email {email} is already in use.");
        }

        return Json(true);
    }
   }
public class ApiHelp
{
    HttpClient _client = new HttpClient();
    SettingHelp _setting = new SettingHelp();
    IdentityServer4Help _serverHelp;
    const string IS_USER_EMAIL_UNIQUE = "User/IsEmailUnique?";
    public CoreApiHelp()
    {
        _serverHelp = new IdentityServer4Help(_setting.IdentityServer4Host, _setting.IdentityServer4ClientId,
            _setting.IdentityServer4ClientSecret, _setting.IdentityServer4ClientScope);
        _client.BaseAddress = new Uri(_setting.ApiHost);
    }
    public async Task<bool> VerifyEmail(string email)
    {
        var token = await _serverHelp.GetToken();
        _client.SetBearerToken(token);
        string uri = $"{IS_USER_EMAIL_UNIQUE}userEmail={email}";
        bool res = false;
        using (var response = await _client.GetAsync(uri))
        {
            await response.EnsureSuccessStatusCodeAsync();
            res = await response.Content.ReadAsAsync<bool>();
        }
        return res;
    }
   }

The code should return true or false after the VerifyEmail api call is executed. However, the execution stalled at the line "await _serverHelp.GetToken();" If I call "VerifyEmail" after "Submit" button is clicked, the api call works fine. It seems there is a problem to call async method for remote validation. Methods in examples for remote validation are sync calls.

Sparky
  • 98,165
  • 25
  • 199
  • 285
user3097695
  • 1,152
  • 2
  • 16
  • 42
  • 2
    Whenever you call an async function with a `.Result` and you have problems you should immediately expect a thread deadlock. Make `ApiHelp.VerifyResult` an `async` method and `await` instead of `.Result`. – Crowcoder Feb 06 '19 at 01:46
  • You are right. I was able to fix the problem by changing the method VerifyEmail to async. – user3097695 Feb 06 '19 at 15:56

0 Answers0