C#中的WebAPI:为什么我不能在另一个公共类的公共类中调用异步任务?

时间:2017-11-14 21:00:15

标签: c# asynchronous asp.net-web-api

我试图从另一个公共类调用公共类中的异步任务,但这是失败的。问题是[public override async Task GrantResourceOwnerCredentials]"中的SendEmailConfirmationTokenAsync在当前上下文中不存在"。私有异步任务位于AccountController.cs中。我该怎么称呼它?

我需要将任务理想地保存在AccountController.cs中,因为它依赖于UserManager.xxx

提前感谢您,任何帮助表示赞赏!

ApplicationOAuthProvider.cs:

namespace BlaBla.Providers
{
    public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
    {
        private readonly string _publicClientId;

        public ApplicationOAuthProvider(string publicClientId)
        {
            if (publicClientId == null)
            {
                throw new ArgumentNullException("publicClientId");
            }

            _publicClientId = publicClientId;
        }

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();

            ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);

            if (user == null)
            {
                context.SetError("invalid_grant", "The user name or password is incorrect.");
                return;
            }

            // if email not confirmed prevent log-in

            if (!await userManager.IsEmailConfirmedAsync(user.Id))
            {
                // resend confirmation mail if not confirmed, but SendEmailConfirmationTokenAsync cannot be found !!!
                string callbackUrl = await SendEmailConfirmationTokenAsync(user.Id, "Resend: Confirm your Blabla account");

                context.SetError("email_not_confirmed", "Please confirm email to be able to log-in.");
                return;
            }

            ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
               OAuthDefaults.AuthenticationType);
            ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
                CookieAuthenticationDefaults.AuthenticationType);

            AuthenticationProperties properties = CreateProperties(user.UserName);
            AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
            context.Validated(ticket);
            context.Request.Context.Authentication.SignIn(cookiesIdentity);
        }

        public override Task TokenEndpoint(OAuthTokenEndpointContext context)
        {
            foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
            {
                context.AdditionalResponseParameters.Add(property.Key, property.Value);
            }

            return Task.FromResult<object>(null);
        }

        public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            // Resource owner password credentials does not provide a client ID.
            if (context.ClientId == null)
            {
                context.Validated();
            }

            return Task.FromResult<object>(null);
        }

        public override Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context)
        {
            if (context.ClientId == _publicClientId)
            {
                Uri expectedRootUri = new Uri(context.Request.Uri, "/");

                if (expectedRootUri.AbsoluteUri == context.RedirectUri)
                {
                    context.Validated();
                }
            }

            return Task.FromResult<object>(null);
        }

        public static AuthenticationProperties CreateProperties(string userName)
        {
            IDictionary<string, string> data = new Dictionary<string, string>
            {
                { "userName", userName }
            };
            return new AuthenticationProperties(data);
        }

    }
}

AccountController.cs:

namespace Blabla.Controller
{
    [Authorize]
    [RoutePrefix("api/Account")]
    public class AccountController : ApiController
    {
        private const string LocalLoginProvider = "Local";
        private ApplicationUserManager _userManager;

        public AccountController()
        {
        }

        public AccountController(ApplicationUserManager userManager,
            ISecureDataFormat<AuthenticationTicket> accessTokenFormat)
        {
            UserManager = userManager;
            AccessTokenFormat = accessTokenFormat;
        }

        public ApplicationUserManager UserManager
        {
            get
            {
                return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
            }
            private set
            {
                _userManager = value;
            }
        }

<..removed lines..>

        // added task for re-send functionality, but not reachable from ApplicationOAuthProvider.cs !!!

        private async Task<string> SendEmailConfirmationTokenAsync(string userID, string subject)
        {
            string code = await UserManager.GenerateEmailConfirmationTokenAsync(userID);

            var callbackUrl = Url.Link("Default", new
            {
                Controller = "api/Account",
                Action = "ConfirmEmail",
                userId = userID,
                code = code
            });

            await UserManager.SendEmailAsync(userID, subject,
               "Please confirm your Blabla account by clicking <a href=\"" + callbackUrl + "\">here</a>");

            return callbackUrl;
        }

        #endregion
    }
}

0 个答案:

没有答案