2012-10-29 11 views
23

Nie mogę spowodować, aby obiekt WebSecurity działał w dowolnym miejscu z wyjątkiem tego, co zostało już wygenerowane w pliku AccountController.cs. Konto administratora ma ustawiony atrybut [InitializeSimpleMembership] u góry. Funkcje logowania nie narzekają na przykład na wywoływanie WebSecurity.Login(...). Dodałem działanie dziecko do AccountController:Musisz wywołać metodę "WebSecurity.InitializeDatabaseConnection" przed wywołaniem jakiejkolwiek innej metody z klasy "WebSecurity"

[ChildActionOnly] 
     [AllowAnonymous] 
     public ActionResult NavBar() 
     { 
      NavBarViewModel viewModel = new NavBarViewModel(); 
      viewModel.LinkItems = new List<NavBarLinkItem>(); 

      if (Request.IsAuthenticated) 
      { 
       SimpleRoleProvider roleProvider = new SimpleRoleProvider(); 
       if (roleProvider.IsUserInRole(User.Identity.Name, "User")) 
       { 
        viewModel.LinkItems.Add(new NavBarLinkItem() 
        { Title = "Create Project", Action = "Create", Controller = "Project" }); 

       } 

      } 

      viewModel.LinkItems.Add(new NavBarLinkItem() { Title="Help", Action="Index", Controller="Help" }); 

      return PartialView("_NavBar", viewModel); 
     } 

Lewy jak jest, wywala kod na "if (roleProvider.IsUserInRole (User.Identity.Name, "User"))" Zgodnie z komunikatem o błędzie przedmiotem. Więc idę do pliku InitialzeSimpleMembershipAttribute.cs i kopiuj/wklej tę linię na szczycie mojej funkcji:

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

... i pojawia się komunikat o błędzie, który WebSecurity.InitializeDatabaseConnection powinna być wywoływana tylko raz. Ma to sens, ponieważ na górze definicji kontrolera znajduje się atrybut, który powinien już wywoływać tę funkcję (i wygląda na to, że tak jest dobrze). Więc pewności, zmieniam powyżej zaproszenia do:

if (!WebSecurity.Initialized) 
      { 
       WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", 
                 "UserName", autoCreateTables: true); 
      } 

... i odzyskać oryginalny komunikat o błędzie, że WebSecurity.InitializeDatabaseConnection powinna zostać wywołana przed bla bla bla. Każdy wgląd w to szaleństwo byłby bardzo mile widziany

Odpowiedz

5

Znalazłem to w interwebs: http://forums.asp.net/t/1718361.aspx/1 Zasadniczo, nie używaj SimpleRoleProvider typu. Jest tam Role obiekt dostępny, które pozwala na proste połączenia tak:

if (Request.IsAuthenticated) 
{ 
    if(Roles.IsUserInRole(User.Identity.Name, "User")) 
    { 
    viewModel.LinkItems.Add(new NavBarLinkItem() 
    { Title = "Create Project", Action = "Create", Controller = "Campaign" }); 
    } 
} 
+1

To naprawdę nie jest tak jasne, jak być może musi. Spojrzałem na link, ale nie ma to związku z tym, co robię (chyba?), Ponieważ nie próbuję utworzyć roli. Mam ten sam problem co ja, dostaję komunikat "nie mogę połączyć się z tym dwa razy", ale kiedy biorę "drugi", otrzymuję komunikat "musisz zadzwonić ...". Przyczyną awarii z komunikatem "musisz zadzwonić ..." jest: , jeśli (OAuthWebSecurity.Login (result.Provider, result.ProviderUserId, createPersistentCookie: false)) Jakieś pomysły? –

9

dodanie [InitializeSimpleMembership] (jak wspomniano i znaleźć w AccountController) do górnej części kontrolera Musiałem przejść WebSecurity z wystarczyły na mnie. Nie jestem pewien, ale jeśli jego zamierzony sposób realizacja chociaż ...

[InitializeSimpleMembership] 
public class DataController : Controller 
{ ... } 
48

Tam jest lepsze wyjaśnienie tutaj: http://odetocode.com/blogs/scott/archive/2012/09/24/perils-of-the-mvc4-accountcontroller.aspx

Oto wszystko, co musisz zrobić:

  1. Usuń [InitializeSimpleMembership] od góry z AccountController
  2. Skopiuj wywołanie WebSecurity.InitializeDatabaseConnection(...) z /Filters/InitializeSimpleMembershipAttribute.cs (wiersz 39) do/AppStart/A uthConfig.cs
  3. Zapraszam do usunięcia InitializeSimpleMembershipAttribute.cs z projektu

Nie mieć dodać wywołanie InitializeDatabaseConnection() do AuthConfig.RegisterAuth() ale wydaje się logicznym miejscu i utrzymuje czystsze global.asax .

Co zasadniczo robisz, to wyodrębnianie wywołania inicjalizacyjnego z oryginalnego atrybutu i jawne wywoływanie go w aplikacji Application_Start. Cała reszta w atrybucie to tylko sprawdzanie warunkowe na wypadek, gdy nie używasz (lub nie potrzebujesz) SimpleMembership.

+0

Udało mi się umieścić atrybut "[InitializeSimpleMembership]" na górze kontrolera i teraz działa. – jwatts1980

+0

Brat wielkiego wyjaśnienia. –

+0

Jakie są tego konsekwencje? Wyobrażam sobie, że tak jest z jakiegoś powodu. – Coops

1

Najpierw musisz ustawić swoją rolę i dostawcę członkostwa w sieci.config:

<authentication mode="Forms"> 
    <forms loginUrl="/Account/Login" slidingExpiration="true" timeout="60" /> 
</authentication> 
<membership defaultProvider="p1"> 
    <providers> 
    <add name="p1" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData"/> 
    </providers> 
</membership> 
<roleManager enabled="true" defaultProvider="p1"> 
    <providers> 
    <add name="p1" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData"/> 
    </providers> 
</roleManager> 

Podczas tworzenia nowej instancji SimpleRoleProvider użyj niezerowym konstruktora i dostarczyć domyślny RoleProvider ustawiony w pliku web.config jako argument:

SimpleRoleProvider srp = new SimpleRoleProvider(Roles.Provider); 

Rozwiązaniem jest tak samo w przypadku SimpleMembershipProvider:

SimpleMembershipProvider msp = new SimpleMembershipProvider(Membership.Provider); 
1

w moim przypadku musiałem wyłączyć dowcip Anonymous Authentication hin ustawienie Uwierzytelnianie IIS.

Następnie musiałem włączyć Forms and Windows Authentication. Oczywiście będzie to zależeć od uwierzytelnienia, którego potrzebujesz dla swojej aplikacji.

Kiedy raz to zrobiłem, błąd zniknął, a aplikacja działała zgodnie z oczekiwaniami.

Powiązane problemy