Подтвердить что ты не робот

Использование SimpleMembership с первой моделью EF

Может ли SimpleMembership использоваться с EF model-first? Когда я пытаюсь, я получаю "Невозможно найти запрошенный поставщик данных .NET Framework", когда я вызываю WebSecurity.InitializeDatabaseConnection.

Другими словами: я не могу заставить вызов WebSecurity.InitializeDatabaseConnection работать, когда в строке подключения используется поставщик System.Data.EntityClient (как и при использовании парадигмы model-first).

Чтобы воспроизвести проблему, создайте приложение MVC 4 и замените класс сущности code-first UserProfile (который вы получаете бесплатно с шаблоном MVC 4) с помощью модели Пользовательский класс, созданный в конструкторе сущностей:

  • Создайте приложение MVC 4 в VS 2012 и добавьте новые, пустые данные Entity Модель.
  • Добавьте новую модель с именем User в модель с полями для Id, UserName, and FullName. Итак, на данный момент объект данных User сопоставлен с таблицей Users и доступен через фанковое соединение строка, в которой используется поставщик System.Data.EntityClient.
  • Убедитесь, что EF может получить доступ к объекту User. Один простой способ сделать то есть для выравнивания контроллера пользователей на основе таблицы User и связанный с ним DbContext.
  • Отредактируйте файл AccountModels.cs, чтобы удалить класс UserProfile и связанный с ним класс UsersContext. Заменить ссылки на (теперь отсутствует) UserProfile и UsersContext классы со ссылками к вашему новому классу User и связанному с ним классу DbContext.
  • Переместите вызов в InitializeDatabaseConnection из Класс InitializeSimpleMembershipAttribute для фильтра Метод Application_Start в Global.asax.cs. Пока вы на нем, изменить аргументы, чтобы использовать новое соединение пользователя строка, имя таблицы и имя столбца UserId.
  • Удалить (больше не используется) InitializeSimpleMembershipAttribute класс и ссылки на него.

При запуске воспроизведения он получит Исключение при вызове InitializeDatabaseConnection.

Боб

4b9b3361

Ответ 1

SimpleMembership может сначала работать с моделью. Вот решение.

1. InitializeSimpleMembershipAttribute.cs из MVC 4 Интернет-приложение храма должно выглядеть следующим образом

namespace WebAndAPILayer.Filters
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public sealed class InitializeSimpleMembershipAttribute : ActionFilterAttribute
    {
        private static SimpleMembershipInitializer _initializer;
        private static object _initializerLock = new object();
        private static bool _isInitialized;

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // Ensure ASP.NET Simple Membership is initialized only once per app start
            LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
        }

        private class SimpleMembershipInitializer
        {
            public SimpleMembershipInitializer()
            {
                try
                {
                    WebSecurity.InitializeDatabaseConnection("ConnStringForWebSecurity", "UserProfile", "Id", "UserName", autoCreateTables: true);
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException("Something is wrong", ex);
                }
            }
        }
    }
}

2.Удалить CodeFirst Classes из AcountModel.cs

3.Fix AccountCotroler.cs для работы с вашим методом DbContext (метод ExternalLoginConfirmation(RegisterExternalLoginModel model, string returnUrl)) Model

4. Определите строку подключения "ConnStringForWebSecurity", которая не такая же, как эта строка funky conn для доступа к первому db для модели, обратите внимание, что мы используем провайдер System.Data.SqlClient not System.Data.EntityClient

 <connectionStrings>
         <add name="ModelFirstEntityFramework" connectionString="metadata=res://*/Context.csdl|res://*/Context.ssdl|res://*/Context.msl;provider=System.Data.SqlClient;provider
 connection string=&quot;data source=.\SQLEXPRESS;Initial
 Catalog=aspnet-MVC4;Integrated
 Security=SSPI;multipleactiveresultsets=True;App=EntityFramework&quot;"
 providerName="System.Data.EntityClient" />
         <add name="ConnStringForWebSecurity" connectionString="data source=.\SQLEXPRESS;Initial Catalog=aspnet-MVC4;Integrated
 Security=SSPI" providerName="System.Data.SqlClient" />
       </connectionStrings>

Ответ 2

Это ошибка в MVC 4. Там обходной путь в этом сообщении в блоге.

В качестве фильтра действий InitializeSimpleMembershipAttribute подключается к OnActionExecuting для выполнения ленивой работы по инициализации, но это может быть слишком поздно в жизненном цикле. Атрибут Authorize будет необходим, чтобы поставщики были готовы раньше, если ему необходимо выполнить проверки доступа на основе ролей (во время OnAuthorization). Другими словами, если первый запрос на сайт попадает в действие контроллера, как показано ниже:

[Authorize(Roles="Sales")]

.. то у вас будет исключение, так как фильтр проверяет роль пользователя, но инициализируется инициатором провайдера.

Моя рекомендация - удалить ISMA из проекта и инициализировать WebSecurity во время запуска приложения.

Ответ 3

1 - Необходимо включить миграцию, предпочтительно с помощью EntityFramework 5

2 - Переместите

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "EmailAddress", autoCreateTables: true); 

к вашему методу Seed в классе YourMvcApp/Migrations/Configuration.cs

    protected override void Seed(UsersContext context)
    {
        WebSecurity.InitializeDatabaseConnection(
            "DefaultConnection",
            "UserProfile",
            "UserId",
            "UserName", autoCreateTables: true);

        if (!Roles.RoleExists("Administrator"))
            Roles.CreateRole("Administrator");

        if (!WebSecurity.UserExists("lelong37"))
            WebSecurity.CreateUserAndAccount(
                "lelong37",
                "password",
                new {Mobile = "+19725000000", IsSmsVerified = false});

        if (!Roles.GetRolesForUser("lelong37").Contains("Administrator"))
            Roles.AddUsersToRoles(new[] {"lelong37"}, new[] {"Administrator"});
    }

Теперь EF5 будет отвечать за создание вашей таблицы UserProfile, после этого вы вызовите WebSecurity.InitializeDatabaseConnection, чтобы зарегистрировать SimpleMembershipProvider с уже созданной таблицей UserProfile (в вашем случае вы можете заменить "UserProfile", значение параметра с вашим пользовательским именем таблицы), также tellling SimpleMembershipProvider, в столбце которого UserId и UserName. Я также показываю пример того, как вы можете добавлять пользователей, роли и связывать их в методе Seed с пользовательскими свойствами/полями UserProfile, например. пользователя Mobile (number).

3 - Теперь, когда вы запускаете базу данных обновлений из Консоли диспетчера пакетов, EF5 предоставит вашей таблице все ваши пользовательские свойства.

Дополнительные ссылки см. в этой статье с исходным кодом: http://blog.longle.net/2012/09/25/seeding-users-and-roles-with-mvc4-simplemembershipprovider-simpleroleprovider-ef5-codefirst-and-custom-user-properties/

Ответ 4

Эта проблема, вызванная WebSecurity.InitializeDatabaseConnection, не может использовать строку подключения с именем поставщика System.Data.EntityClient.

обеспечение двойной строки соединения не очень хорошо, поэтому вы можете генерировать строку подключения для модели EF сначала в конструкторе в частичном классе.

код выглядит следующим образом

public partial class MyDataContext 
{
    private static string GenerateConnectionString(string connectionString)
    {
        var cs = System.Configuration.ConfigurationManager
                     .ConnectionStrings[connectionString];

        SqlConnectionStringBuilder sb = 
             new SqlConnectionStringBuilder(cs.ConnectionString);
        EntityConnectionStringBuilder builder = 
             new EntityConnectionStringBuilder();
        builder.Provider = cs.ProviderName;
        builder.ProviderConnectionString = sb.ConnectionString;
        builder.Metadata = "res://*/MyDataContext.csdl|" +
              "res://*/MyDataContext.ssdl|res://*/MyDataContext.msl";
        return builder.ToString();
    }

    public MyDataContext(string connectionName) : 
          base(GenerateConnectionString(connectionName)) { }
}

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

Ответ 5

Я не могу работать с классом WebSecurity EF и WebMatrix, чтобы избежать этой проблемы и продолжать:

Сначала измените мою модель Ef на код.

Измените строку подключения на использование providerName = "System.Data.SqlClient" (удалите всю информацию метаданных) или используйте соединение EF

В моем случае модель, данные и веб - разные proyects, поэтому для меня не проблема удалить эту информацию из web.config в web.project.

В настоящее время websecuroty.initializedatabase не работает со строкой соединения EF.

Я хочу, чтобы это помогло