25

除了 AccountController.cs 文件中已经生成的内容外,我无法让 WebSecurity 对象在任何地方工作。帐户控制器[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, "User"))" 行与主题错误消息一起崩溃。所以我进入 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 应该在等等等等之前调用。任何对这种疯狂的洞察力将不胜感激

4

5 回答 5

49

这里有一个更好的解释:http: //odetocode.com/blogs/scott/archive/2012/09/24/perils-of-the-mvc4-accountcontroller.aspx

这是您所要做的一切:

  1. [InitializeSimpleMembership]从顶部删除AccountController
  2. WebSecurity.InitializeDatabaseConnection(...)调用从 /Filters/InitializeSimpleMembershipAttribute.cs(第 39 行)复制到 /AppStart/AuthConfig.cs
  3. 随意从您的项目中删除 InitializeSimpleMembershipAttribute.cs

您不必InitializeDatabaseConnection()调用添加到,但AuthConfig.RegisterAuth()它似乎是合乎逻辑的地方,可以让您的 Global.asax 保持清洁。

您实际上所做的是从原始属性中提取初始化调用并在 Application_Start 上显式调用它。如果您不使用(或不需要)SimpleMembership,属性中的其他所有内容都只是条件检查。

于 2013-04-07T15:31:00.613 回答
9

将 [InitializeSimpleMembership](如在 AccountController 中提到并找到)添加到我需要从中访问 WebSecurity 的控制器的顶部对我来说是诀窍。但是不确定它是否是预期的实现方法......

[InitializeSimpleMembership]
public class DataController : Controller
{ ... }
于 2013-01-29T16:36:05.990 回答
5

我在互联网上找到了这个: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" });
  }
}
于 2012-10-29T19:44:04.470 回答
1

首先,您必须在 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 的新实例时,请使用非 null 构造函数,并提供 web.config 中设置的默认 RoleProvider 作为参数:

SimpleRoleProvider srp = new SimpleRoleProvider(Roles.Provider);

在 SimpleMembershipProvider 的情况下解决方案是相同的:

SimpleMembershipProvider msp = new SimpleMembershipProvider(Membership.Provider);
于 2013-10-13T18:01:35.627 回答
1

在我的情况下,我必须在 IIS 身份验证设置中禁用匿名身份验证。

然后我必须启用表单和 Windows 身份验证。这当然取决于您对应用程序需要的任何身份验证。

一旦我这样做了,错误就消失了,应用程序按预期工作。

于 2015-05-29T09:08:32.637 回答