0

I have an external-facing SharePoint site that uses a .Net membership database to house claims user accounts. I'm attempting to build a solution in C# that creates a new user account in the database and (so far) coming up short.

For instance, imagine I have a "Create User" button on the ribbon and when someone clicks that button I want the following to happen:

  1. solution logs in to the account database using hard-coded credentials
  2. solution creates a new account using a variable from the page as the login name
  3. solution generates a random password for the account
  4. solution places the account in a hard-coded SharePoint group on the site

Seems easy enough on the face of it, but I'm running into issues accessing the database and creating new rows in multiple tables. I've added the database to my solution as a data source, but that may not be the correct method. Several articles indicate adding the database as a membership provider, but I don't need to authenticate against the existing accounts, just create a new one. Unfortunately, that act seems to touch multiple tables at once when done through the GUI.

What would be the correct method in C# for accessing the database and creating a new user account? Assume either a web form application or a SharePoint feature solution.

1

This answer assumes you are using a standard SQL Membership Provider and vanilla database. (And this is not really a SharePoint issue, this is more of a .NET issue you are implementing in a SharePoint context.)

Essentially, what you want to do is insert some rows into a database. There are a number of ways to access a database, but I prefer Entity Framework. EF creates a series of strongly typed entity classes that serve as your API into the database. I create users by mapping the Membership_CreateUser stored proc into an EF entity, and call it like this:

public static int CreateAUser(string appName, string username, string password)
        {
            int outResult = 0;
            using (var db = new MembershipEntities( ))  //the name of the EF context
            {
                var outputParam = new ObjectParameter("userId", typeof(int));
                outResult = db.aspnet_Membership_CreateUser(appName, username, password, "", username, "", "", true, DateTime.Now, DateTime.Now, 0, 0, outputParam);
            }

            return outResult;
        }

The sproc handles all the INSERT statements so you don't have to worry about all that's going on under the covers (but I highly recommend you examine the sproc so you know what's going on). The method will return the numeric ID of the database row created in the Membership table, which may or may not be useful to you. Intellisense (and peeking at the sproc itself) should help you figure out what all the parameters are for. Your needs might require a different configuration.

You can generate a password by calling the built-in function in System.Web.Security.Membership:

string password = Membership.GeneratePassword(8, 2);  
 // 8 characters, 2 non-alphanumeric characters

You would call the code like this:

Your.Code.Library.CreateUser("/", email, password);

Then, to put the user into that group:

SPUser theUser = elevatedSite.RootWeb.EnsureUser("i:0#.f|ext|" + email);

//you need to use EnsureUser in an elevated code block (which I assume you know how to do)
//that crazy string you see before the email is the claims prefix for the user where "ext" is the name of the membership provider registered in web.config
//you'll want to change that to whatever your environment uses

 theUser.Name = string.Format("{0} {1}", userFirstname, userlastName); 

//not really necessary but it's nice to have user names formatted nicely

theUser.Update();


//add the user to the group
SPGroup theGroup = elevatedSite.RootWeb.Groups["FBA Users"];
theGroup.AddUser(theUser);
theGroup.Update();

Lastly, and this might be beyond your scope or willingness to do, but I highly recommend putting all your membership data access code in a separate code library project. This will make it reusable and modular and will help with maintainability.

Entity Framework http://msdn.microsoft.com/en-us/data/ee712907.aspx

Membership API http://msdn.microsoft.com/en-us/library/system.web.security.membership(v=vs.110).aspx

  • Question: In your top snippet, where is "MembershipEntities" coming from? It doesn't seem to be a method in either System.Web or System.Web.Security, unless I'm looking in the wrong place. Are you manually defining that elsewhere? – Omegacron Dec 16 '14 at 19:56
  • It's the class generated by the Entity Framework wizard. For example, if you create an EF model against the Northwind DB, you'll get a class called "NorthwindEntities". In my case above I named my database "Membership". – Derek Gusoff Dec 16 '14 at 22:38
  • Ah, ok - so if I named my EF model "AppAccountsDB" I would use "AppAccountsDBEntities"? Sorry, I'm new to Entity Framework usage. – Omegacron Dec 16 '14 at 22:40
  • Probably. I would find a tutorial on EF and see if that's the direction you want to go. If you're more comfortable with ADO.NET or some other data access technology, you can forget the EF stuff and just wire up that stored procedure in the technology of your choice. – Derek Gusoff Dec 16 '14 at 22:53
  • I'll see if I can crack the EF way - the way I see it, every new technology I can learn just makes me more valuable as an employee. Plus... bragging rights. – Omegacron Dec 16 '14 at 22:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.