在调用“WebSecurity”类的任何其他方法之前,必须调用“WebSecurity.InitializeDatabaseConnection”方法

时间:2012-10-29 19:19:52

标签: asp.net asp.net-mvc-4

除了在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);
            }

...并返回原始错误消息,应该在blah blah blah之前调用WebSecurity.InitializeDatabaseConnection。任何对这种疯狂的见解都将非常感激

5 个答案:

答案 0 :(得分:49)

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

以下是您所要做的一切:

  1. [InitializeSimpleMembership]
  2. 的顶部移除AccountController
  3. WebSecurity.InitializeDatabaseConnection(...)来自/Filters/InitializeSimpleMembershipAttribute.cs(第39行)的电话复制到/AppStart/AuthConfig.cs
  4. 随意从项目中删除InitializeSimpleMembershipAttribute.cs
  5. 您没有 InitializeDatabaseConnection()电话添加到AuthConfig.RegisterAuth(),但它似乎是合乎逻辑的地方,让您的Global.asax更加清洁。

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

答案 1 :(得分:9)

将[InitializeSimpleMembership](如上所述,在AccountController中找到)添加到我需要访问WebSecurity的控制器顶部,这对我来说很有用。但是不确定它是否是预期的实现方法......

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

答案 2 :(得分:5)

我在互联网上发现了这个:http://forums.asp.net/t/1718361.aspx/1 基本上,不要使用SimpleRoleProvider类型。有一个可用的角色对象允许这样的简单调用:

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

答案 3 :(得分: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);

答案 4 :(得分:1)

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

然后我必须启用表单和Windows身份验证。 这当然取决于您的应用所需的身份验证。

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