Korzystanie z SimpleMembership z modelem EF-najpierw
Czy SimpleMembership może być używany z EF model-first? Kiedy próbuję, dostaję "nie można znaleźć żądanego dostawcy danych. NET Framework", gdy wywołuję WebSecurity.InitializeDatabaseConnection.
By ująć to inaczej: nie mogę uzyskać wywołania WebSecurity.InitializeDatabaseConnection
do pracy, gdy łańcuch połączenia używa dostawcy System.Data.EntityClient
(Jak to robi, gdy używa paradygmatu model-first ).
Aby ponownie rozwiązać problem, utwórz aplikację MVC 4 i zamień code-first UserProfile entity class (która otrzymujesz za darmo szablon MVC 4) z model-pierwsza klasa Użytkownika, którą utworzyłeś w encji Designer:
- Utwórz aplikację MVC 4 w VS 2012 i dodaj nowe, puste dane encji Model.
- Dodaj do modelu nową jednostkę o nazwie
User
z polami dlaId,
UserName, and FullName
. Zatem w tym momencie podmiotUser
danych jest mapowane do tabeliUsers
i jest dostępne za pomocą funky connection string, który używa dostawcySystem.Data.EntityClient
. - sprawdź, czy EF może uzyskać dostęp do podmiotu
User
. Jeden łatwy sposób czyli rusztowanie kontrolera Users w oparciu o tabelę User i związany z nim DbContext. - Edytuj plik
AccountModels.cs
, aby usunąć klasęUserProfile
i jego powiązana KlasaUsersContext
. Zastąp odniesienia do (obecnie brak)UserProfile
iUsersContext
klasy z referencjami do nowej klasy użytkownika i powiązanej z nią klasyDbContext
. - Przenieś wywołanie do InitializeDatabaseConnection z InitializeSimpleMembershipAttribute Klasa filtra do Application_Start method in Global.asax.cs. While you ' re at it, zmodyfikuj argumenty, aby użyć połączenia nowej jednostki użytkownika ciąg znaków, nazwa tabeli i nazwa kolumny UserId.
- Usuń (już nie używany)
InitializeSimpleMembershipAttribute
klasa i odniesienia do niej.
InitializeDatabaseConnection.
Bob
5 answers
SimpleMembership może najpierw pracować z modelem. Oto rozwiązanie.
1.InitializeSimpleMembershipAttribute.cs
szablon aplikacji internetowej MVC 4 powinien wyglądać tak
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.Delete CodeFirst Classes from AcountModel.cs
3.Fix AccountCotroler.cs
do pracy z Modelem - pierwsza metoda DbContext (ExternalLoginConfirmation(RegisterExternalLoginModel model, string returnUrl)
)
4.Zdefiniuj swój łańcuch połączeń "ConnStringForWebSecurity"
, który nie jest taki sam jak łańcuch połączeń dla pierwszego dostępu db, zauważ, że używamy provider System.Data.SqlClient
, a nie 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="data source=.\SQLEXPRESS;Initial
Catalog=aspnet-MVC4;Integrated
Security=SSPI;multipleactiveresultsets=True;App=EntityFramework""
providerName="System.Data.EntityClient" />
<add name="ConnStringForWebSecurity" connectionString="data source=.\SQLEXPRESS;Initial Catalog=aspnet-MVC4;Integrated
Security=SSPI" providerName="System.Data.SqlClient" />
</connectionStrings>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-23 19:33:55
To błąd w MVC 4. jest obejście w tym poście na blogu .
Jako filtr akcji,
InitializeSimpleMembershipAttribute
zaczepia się doOnActionExecuting
, aby wykonać leniwą pracę inicjalizacyjną, ale może to być zbyt późno w cyklu życia. Atrybut Authorize będzie wymagał, aby dostawcy byli gotowi wcześniej, jeśli będą musieli sprawdzić dostęp w oparciu o role (podczasOnAuthorization
). Innymi słowy, jeśli pierwsze żądanie do witryny trafi w akcję kontrolera, taką jak:
[Authorize(Roles="Sales")]
.. wtedy będziesz mieć wyjątek, ponieważ filtr sprawdza rolę użytkownika, ale dostawcy nie są inicjowani.
Zalecam usunięcie ISMA z projektu i zainicjowanie WebSecurity podczas zdarzenia start aplikacji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-25 13:48:46
1 - Musisz włączyć migracje, najlepiej z EntityFramework 5
2-Przenieś swoje
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "EmailAddress", autoCreateTables: true);
Do metody Seed w YourMvcApp / Migrations / Configuration.Klasa 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"});
}
Teraz EF5 będzie odpowiedzialny za tworzenie tabeli UserProfile, po zrobieniu tego wywołasz WebSecurity.InitializeDatabaseConnection rejestruje tylko SimpleMembershipProvider z już utworzoną tabelą UserProfile (w Twoim przypadku możesz zastąpić parametr "UserProfile" wartość z niestandardową nazwą tabeli) , również mówi SimpleMembershipProvider, która kolumna jest UserId i UserName. Pokazuję również przykład, w jaki sposób można dodać użytkowników, role i powiązać te dwa w swojej metodzie zalążkowej z niestandardowymi właściwościami/polami UserProfile, np.
3-Teraz, gdy uruchomisz update-database z konsoli Menedżera pakietów, EF5 udostępni Twoją tabelę ze wszystkimi własnymi właściwościami
Aby uzyskać dodatkowe odniesienia, zapoznaj się z tym artykuł z kodem źródłowym: http://blog.longle.net/2012/09/25/seeding-users-and-roles-with-mvc4-simplemembershipprovider-simpleroleprovider-ef5-codefirst-and-custom-user-properties/
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-29 23:47:33
Ten problem spowodowany przez WebSecurity.InitializeDatabaseConnection
nie może używać łańcucha połączenia z nazwą dostawcy System.Data.EntityClient
.
Zapewnienie ciągu podwójnego połączenia nie brzmi dobrze, więc możesz wygenerować Łańcuch Połączenia dla modelu EF najpierw w konstruktorze w klasie częściowej.
Kod wygląda jak poniżej
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)) { }
}
Dzięki tej sztuczce możesz użyć pojedynczego ciągu połączenia w konfiguracji web, ale jeden problem nie możesz użyć domyślnego konstruktora w datacontext, zamiast tego powinieneś zalać łańcuch połączenia wymień wszędzie, gdy tworzysz instancję datacontext. ale nie jest to duży problem, gdy używasz wzorca wtrysku zależności.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-13 23:30:20
Im nie może pracować z klasą EF i WebMatrix webSecurity, więc aby uniknąć tego problemu i iść do przodu:
Zmień najpierw mój model Ef na kod.
Zmień łańcuch połączeń na providerName= " System.Data.SqlClient " (usuwanie wszystkich informacji metadanych) lub użyj połączenia EF
W moim przypadku model, Dane i web są różne proyects więc dla mnie nie jest problemem, aby usunąć te informacje z sieci.config w sieci.projekt.
Obecnie websecuroty.initializedatabase nie uruchamia się z łańcuchem połączeń EF.
I wish this helps
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-01 07:34:01