Oxygen
Oxygen

Reputation: 871

How to execute await method in MVC

We are using Microsoft Graph SDK. Implemented a POC in console application where the code works fine but when added this code in MVC its not working. code stucks at await call

Calling from controller as

 [HttpPost]
    public ActionResult InviteUser([Bind(Include = "EmailId")] UserLogin userLogin)
    {
        if (ModelState.IsValid)
        {
            string result = AzureADUtil.InviteUser(userLogin.EmailId);
        }
        return View();
    }

Method implementation is as below

  public static string InviteUser(string emailAddress)
    {
        string result = string.Empty;

        result = InviteNewUser(emailAddress).Result;

        return result;

    }

    private static async Task<string> InviteNewUser(string emailAddress)
    {
        string result = string.Empty;
        try
        {
            IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
            .Create(clientId)
            .WithTenantId(tenantID)
            .WithClientSecret(clientSecret)
            .Build();

            ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);

            GraphServiceClient graphClient = new GraphServiceClient(authProvider);

            // Send Invitation to new user
            var invitation = new Invitation
            {
                InvitedUserEmailAddress = emailAddress,
                InviteRedirectUrl = "https://myapp.com",
                SendInvitationMessage = true,
                InvitedUserType = "Member" 

            };

            // It stucks at this line
            await graphClient.Invitations
            .Request()
            .AddAsync(invitation);

        }
        catch (Exception ex)
        {
            result = ex.Message;
        }
        return result;

    }

Upvotes: 1

Views: 430

Answers (2)

Nkosi
Nkosi

Reputation: 247098

Mixing async-await and blocking code like .Result or .Wait() tends to lead to deadlocks, especially on asp.net-mvc.

If going async then go all the way.

[HttpPost]
public async Task<ActionResult> InviteUser([Bind(Include = "EmailId")] UserLogin userLogin) {
    if (ModelState.IsValid) {
        string result = await AzureADUtil.InviteUser(userLogin.EmailId);
    }
    return View();
}

With implementation refactored to be async as well

public static async Task<string> InviteUser(string emailAddress)
{
    string result = string.Empty;

    result = await InviteNewUser(emailAddress);

    return result;
}

InviteUser is now redundant since it basically wraps the private InviteNewUser call.

Reference Async/Await - Best Practices in Asynchronous Programming

Upvotes: 2

peinearydevelopment
peinearydevelopment

Reputation: 11474

The best would be to update your code to run async the whole way down the request chain. You could do that as follows:

[HttpPost]
public async Task<ActionResult> InviteUser([Bind(Include = "EmailId")] UserLogin userLogin)
{
    if (ModelState.IsValid)
    {
        string result = await AzureADUtil.InviteNewUser(userLogin.EmailId).ConfigureAwait(false);
    }
    return View();
}

Upvotes: 0

Related Questions