Использование SimpleMembership с первой моделью EF
Может ли SimpleMembership использоваться с EF-моделью ? Когда я пытаюсь, я получаю «Невозможно найти запрашиваемого поставщика данных .NET Framework» при вызове WebSecurity.InitializeDatabaseConnection.
WebSecurity.InitializeDatabaseConnection
говоря: я не могу получить вызов WebSecurity.InitializeDatabaseConnection
для работы, когда в строке подключения используется поставщик System.Data.EntityClient
(как и при использовании парадигмы модели ).
Чтобы воспроизвести проблему, создайте приложение MVC 4 и замените первый class classа UserProfile (который вы получаете бесплатно с шаблоном MVC 4) с первым classом пользователя, созданным в Entity Designer:
- сочетание двух полей должно быть уникальным в первом подходе кода Entity Framework. как это было бы?
- Проблемы с картой One-To-One от Entity Framework
- Пейджинг в инфраструктуре Entity
- Entity Framework - Получить список таблиц
- Как обеспечить, чтобы прокси создавались при использовании шаблона репозитория с каркасом сущности?
- Создайте приложение MVC 4 в VS 2012 и добавьте новую, пустую модель данных сущности.
- Добавьте в модель новый объект с именем
User
с полямиId,
UserName, and FullName
. Итак, на данный момент объект данныхUser
сопоставляется с таблицей «Users
и доступен через фанк-строку соединения, в которой используется поставщикSystem.Data.EntityClient
. - Убедитесь, что EF может получить доступ к объекту
User
. Один простой способ сделать это – выставить controller пользователей на основе таблицы User и связанного с ним DbContext. - Отредактируйте файл
AccountModels.cs
чтобы удалить classUserProfile
и связанный сUsersContext
classUsersContext
. Замените ссылки на classы (теперь отсутствующие)UserProfile
иUsersContext
со ссылками на ваш новый class User и связанный сDbContext
classDbContext
. - Переместите вызов в InitializeDatabaseConnection из classа фильтра InitializeSimpleMembershipAttribute на метод Application_Start в Global.asax.cs. Пока вы на это, измените аргументы, чтобы использовать новую строку подключения пользователя, имя таблицы и имя столбца UserId.
- Удалите (не используется) class
InitializeSimpleMembershipAttribute
и ссылки на него.
Когда вы запустите воспроизведение, он получит Исключение при вызове InitializeDatabaseConnection.
боб
- Entity Framework - Почему явным образом задал состояние объекта для изменения?
- Entity Framework: «Заявление об обновлении, вставке или удалении влияет на неожиданное количество строк (0)».
- Как использовать свойства интерфейса с помощью CodeFirst
- Код структуры Entity сначала создает столбец «дискриминатор»
- Entity Framework: игнорировать столбцы
- Entity Framework 4.1 DbContext переопределяет SaveChanges для изменения свойств аудита
- Поставщик службы Entity Framework не найден для поставщика ADO.NET с инвариантным именем «System.Data.SqlClient»
- Запрос EF с условным включением
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.Удалить classы AcountModel.cs
из AcountModel.cs
3.Fix AccountCotroler.cs
для работы с вашим методом Model-first DbContext (метод ExternalLoginConfirmation(RegisterExternalLoginModel model, string returnUrl)
)
4. "ConnStringForWebSecurity"
строку соединения "ConnStringForWebSecurity"
которая не такая же, как и эта фанковая строка для первого доступа к базе данных, заметим, что мы используем провайдер System.Data.SqlClient
not System.Data.EntityClient
Это ошибка в MVC 4. В этом сообщении блога есть обходное решение .
В качестве фильтра действий
InitializeSimpleMembershipAttribute
OnActionExecuting
кOnActionExecuting
для выполнения ленивой работы по инициализации, но это может быть слишком поздно в жизненном цикле. Атрибут Authorize будет необходимо, чтобы поставщики были готовы раньше, если ему необходимо выполнить проверки доступа на основе ролей (во времяOnAuthorization
). Другими словами, если первый запрос на сайт касается действия controllerа, например:
[Authorize(Roles="Sales")]
.. тогда у вас будет исключение, так как фильтр проверяет роль пользователя, но поставщики не инициализируются.
Моя рекомендация – удалить ISMA из проекта и инициализировать WebSecurity во время запуска приложения.
1 – Вам необходимо включить миграцию, предпочтительно с EntityFramework 5
2 – Переместите
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "EmailAddress", autoCreateTables: true);
к методу Seed в classе 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» вашей пользовательской таблицей name) , также 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-свойства /
эта проблема, вызванная WebSecurity.InitializeDatabaseConnection
не может использовать строку подключения с именем поставщика System.Data.EntityClient
.
предоставление двойной строки соединения не очень хорошо, поэтому вы можете генерировать строку соединения для модели EF сначала в конструкторе в частичном classе.
код выглядит чуть ниже
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. но это не большая проблема, когда вы используете шаблон инъекции зависимостей.
Я не могу работать с classом WebSecurity EF и WebMatrix, чтобы избежать этой проблемы и продолжать:
Сначала измените мою модель Ef на код.
Измените строку подключения на использование providerName = «System.Data.SqlClient» (удалите всю информацию метаданных) или используйте соединение EF
В моем случае модель, данные и веб – разные proyects, поэтому для меня не проблема удалить эту информацию из web.config в web.project.
В настоящее время websecuroty.initializedatabase не работает со строкой соединения EF.
Я хочу, чтобы это помогло