Вы должны вызвать метод "WebSecurity.InitializeDatabaseConnection", прежде чем вы вызовете любой другой метод класса "WebSecurity"
Я не могу заставить объект WebSecurity работать в любом месте, кроме того, что уже было создано в файле AccountController.cs. Контроллер учетной записи имеет атрибут [InitializeSimpleMembership]
, расположенный сверху. Например, функции входа в систему не жалуются на вызов WebSecurity.Login(...)
. Я добавил дочернее действие в AccountController:
[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);
}
Влево, как есть, код падает на "if (roleProvider.IsUserInRole(User.Identity.Name," Пользователь "))" строка с сообщением об ошибке объекта. Поэтому я перехожу в файл InitialzeSimpleMembershipAttribute.cs и копирую/вставляю эту строку в верхней части моей функции:
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
... и получите сообщение об ошибке, что WebSecurity.InitializeDatabaseConnection следует вызывать только один раз. Это имеет смысл, потому что в верхней части определения контроллера есть атрибут, который должен был вызвать эту функцию уже (и, похоже, это просто отлично). Чтобы быть в безопасности, я перехожу выше:
if (!WebSecurity.Initialized)
{
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId",
"UserName", autoCreateTables: true);
}
... и вернуть исходное сообщение об ошибке, что WebSecurity.InitializeDatabaseConnection следует вызывать перед бла-бла-бла. Любое понимание этого безумия получило бы высокую оценку
Ответы
Ответ 1
Я нашел это в interwebs: http://forums.asp.net/t/1718361.aspx/1
В принципе, не используйте SimpleRoleProvider. Доступен объект Roles, который позволяет простыми вызовами, например:
if (Request.IsAuthenticated)
{
if( Roles.IsUserInRole(User.Identity.Name, "User"))
{
viewModel.LinkItems.Add(new NavBarLinkItem()
{ Title = "Create Project", Action = "Create", Controller = "Campaign" });
}
}
Ответ 2
Здесь есть лучшее объяснение:
http://odetocode.com/blogs/scott/archive/2012/09/24/perils-of-the-mvc4-accountcontroller.aspx
Здесь все, что вам нужно сделать:
- Удалите
[InitializeSimpleMembership]
сверху AccountController
- Скопируйте вызов
WebSecurity.InitializeDatabaseConnection(...)
из /Filters/InitializeSimpleMembershipAttribute.cs(строка 39) в /AppStart/AuthConfig.cs
- Не забудьте удалить InitializeSimpleMembershipAttribute.cs из вашего проекта.
Вам не нужно добавлять вызов InitializeDatabaseConnection()
к AuthConfig.RegisterAuth()
, но он выглядит как логическое место и сохраняет ваш очиститель Global.asax.
По сути дела, вы извлекаете вызов инициализации из исходного атрибута и явно вызываете его на Application_Start. Все остальное в атрибуте - это просто условная проверка, если вы не используете (или не нуждаетесь) SimpleMembership.
Ответ 3
Добавление [InitializeSimpleMembership] (как упоминалось и найдено в AccountController) на вершину контроллера, с которым мне нужно было получить доступ к WebSecurity, помогло. Не уверен, однако, если его предполагаемый метод реализации, хотя...
[InitializeSimpleMembership]
public class DataController : Controller
{ ... }
Ответ 4
Сначала вы должны установить свою роль и поставщика членства в файле web.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>
Когда вы создаете новый экземпляр SimpleRoleProvider, используйте конструктор, отличный от нуля, и поставьте установленный по умолчанию RoleProvider в файле web.config как аргумент:
SimpleRoleProvider srp = new SimpleRoleProvider(Roles.Provider);
Решение одинаково в случае SimpleMembershipProvider:
SimpleMembershipProvider msp = new SimpleMembershipProvider(Membership.Provider);
Ответ 5
В моем случае я должен был отключить анонимную аутентификацию в настройке проверки подлинности IIS.
Затем мне пришлось включить Forms и Windows Authentication. Это, конечно, будет зависеть от того, какая аутентификация вам требуется для вашего приложения.
Как только я это сделал, ошибка исчезла, и приложение работало, как ожидалось.