Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

You must call the "WebSecurity.InitializeDatabaseConnection" method before you call any other method of the "WebSecurity" class

I can't make WebSecurity object work anywhere except what's already been generated in AccountController.cs file. Account controller has [InitializeSimpleMembership] attribute set at the top. Login functions don't complain about calling WebSecurity.Login(...), for example. I added a child action to 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);
        }

Left as is, the code crashes on "if (roleProvider.IsUserInRole(User.Identity.Name, "User"))" line with the subject error message. So I go into InitialzeSimpleMembershipAttribute.cs file and copy/paste this line at the top of my function:

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

... and get an error message that WebSecurity.InitializeDatabaseConnection should only be called once. This makes sense, because there is an attribute at the top of the controller definition that should've called this function already (and it seems it does that just fine). So to be safe, I change above call to:

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

... and get back the original error message, that WebSecurity.InitializeDatabaseConnection should be called before blah blah blah. Any insight into this madness would be greatly appreciated

like image 870
Alex Polkhovsky Avatar asked Oct 29 '12 19:10

Alex Polkhovsky


3 Answers

There's a better explanation here: http://odetocode.com/blogs/scott/archive/2012/09/24/perils-of-the-mvc4-accountcontroller.aspx

Here's all you have to do:

  1. Remove [InitializeSimpleMembership] from the top of AccountController
  2. Copy the WebSecurity.InitializeDatabaseConnection(...) call from /Filters/InitializeSimpleMembershipAttribute.cs (line 39) to /AppStart/AuthConfig.cs
  3. Feel free to remove InitializeSimpleMembershipAttribute.cs from your project

You don't have to add the InitializeDatabaseConnection() call to AuthConfig.RegisterAuth() but it seems like the logical place and keeps your Global.asax cleaner.

What you are essentially doing is extracting the initialization call from the original attribute and explicitly calling it on Application_Start. Everything else in the attribute is just conditional checking in case you aren't using (or don't need) SimpleMembership.

like image 146
Neil Laslett Avatar answered Nov 13 '22 20:11

Neil Laslett


Adding the [InitializeSimpleMembership] (as mentioned and found in the AccountController) to the top of the controller I needed to access WebSecurity from did the trick for me. Not sure however if its the intended implementation method though...

[InitializeSimpleMembership]
public class DataController : Controller
{ ... }
like image 9
roadsunknown Avatar answered Nov 13 '22 19:11

roadsunknown


I found this on the interwebs: http://forums.asp.net/t/1718361.aspx/1 Basically, don't use SimpleRoleProvider type. There is a Roles object available that allows simple calls like this:

if (Request.IsAuthenticated)
{
  if( Roles.IsUserInRole(User.Identity.Name, "User"))
  {
    viewModel.LinkItems.Add(new NavBarLinkItem() 
    { Title = "Create Project", Action = "Create", Controller = "Campaign" });
  }
}
like image 5
Alex Polkhovsky Avatar answered Nov 13 '22 20:11

Alex Polkhovsky