4

У меня есть проект MVC 5, который был модифицирован, чтобы использовать INT в качестве первичного ключа идентичности, как показано в этом guide«Нет IUserTokenProvider не зарегистрирован» при использовании инъекции StructureMap зависимостей

я позволил подтверждение по электронной почте, как описано в this guide

Все работало нормально, как ожидалось. Затем я установил structuremap.mvc5 для инъекции зависимостей и добавлен модифицированный DefaultRegistry.cs к

public DefaultRegistry() { 
     Scan(
      scan => { 
       scan.TheCallingAssembly(); 
       scan.WithDefaultConventions(); 
       scan.AssemblyContainingType(typeof(MyProject.Data.MyDbContext)); 
       scan.With(new ControllerConvention()); 
      }); 
     //For<IExample>().Use<Example>(); 
     For<IUserStore<ApplicationUser, int>>().Use<MyUserStore>().LifecycleIs<HttpContextLifecycle>(); 
     For<IAuthenticationManager>().Use(() => HttpContext.Current.GetOwinContext().Authentication); 

    } 

Проект строит хорошо, но при попытке зарегистрировать новый пользователь на сайте, подтверждение отправки электронной почты в настоящее время бросает исключение System.NotSupportedException : IUserTokenProvider не зарегистрирован при вызове UserManager.GenerateEmailConfirmationTokenAsync (userID).

private async Task<string> SendEmailConfirmationTokenAsync(int userID, string subject) 
    { 
     string code = await UserManager.GenerateEmailConfirmationTokenAsync(userID); 
     var callbackUrl = Url.Action("ConfirmEmail", "Account", 
      new { userId = userID, code = code }, protocol: Request.Url.Scheme); 
     await UserManager.SendEmailAsync(userID, subject, 
      "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>"); 

     return callbackUrl; 
    } 

Я новичок в инъекции зависимостей и уверен, что я делаю что-то неправильно. Я буду благодарен за ваши мысли и идеи.

+0

Как вы настроили свой «UserManager»? –

+0

@HamletHakobyan Я использовал определение UserManger по умолчанию, которое получает экземпляр из контекста owin и не выполняет никаких конфигураций. В конце концов я закончил делать что-то похожее на http://stackoverflow.com/questions/26240873/issues-configuring-structuremap-mvc5-to-work-with-identity, но хотел бы знать, есть ли лучший подход, поскольку это больше похоже на взломать. – dipole

ответ

5

IUserTokenProvider по умолчанию вставлен OWIN, но когда вы разрешаете UserManager из вашего контейнера DI, компонент, который обеспечивает IUserTokenProvider, недоступен, и этот компонент не инициализирован.

Вы должны назначить маркер поставщика к глобальной статической переменной, когда он доступен, а затем повторно использовать его в UserManager конструктору:

public class AuthConfig 
{ 
    public static IDataProtectionProvider DataProtectionProvider { get; set; } 

    public void Configuration(IAppBuilder app) 
    { 
     ConfigureAuth(app); 
    } 

    public void ConfigureAuth(IAppBuilder app) 
    { 
     DataProtectionProvider = app.GetDataProtectionProvider(); 

     // do other configuration 
    } 
} 

А затем повторно назначить его в конструктор UserManager конструктора :

public UserManager(/*your dependecies*/) 
{ 
    var dataProtectorProvider = AuthConfig.DataProtectionProvider; 
    var dataProtector = dataProtectorProvider.Create("My Asp.Net Identity"); 
    this.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser, Guid>(dataProtector) 
    { 
     TokenLifespan = TimeSpan.FromHours(24), 
    }; 
    // other stuff 
} 
+0

Спасибо за разъяснение. Это похоже на то, что я сделал до сих пор. – dipole

Смежные вопросы