How to create the first user in the Membership database

D

David Thielen

Hi;

We have a C# Windows app for our setup program that creates the membership
DB using aspnet_regsql. But we then need to create the standard roles and
sysadmin user from this windows app - we are not in ASP.NET.

How do we do this? It seems to me that the sysadmin user must always be
created before the ASP.NET app ever runs - otherwise no one can log in to
create users.

--
thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm
 
S

Steven Cheng[MSFT]

Hello Dave,

As for the ASP.NET SqlMembership provider, if you want to do some database
initialization tasks (such as create some users) out side the ASP.NET
application context), you can manually call the SqlMembershipProvider in
console or winform application. What you need to do is first call
SqlMembershipProvider.Initialize method and passs in the correct name/value
configuration pairs. e.g.


========in winform codebehind=======
public partial class Form1 : Form
{
SqlMembershipProvider _provider = null;

public Form1()
{
InitializeComponent();
}

private void btnCreate_Click(object sender, EventArgs e)
{
MembershipCreateStatus ret;

MembershipUser user = _provider.CreateUser(
txtUsername.Text,
txtPassword.Text,
txtUsername.Text + "@test.org",
"who am i?",
txtUsername.Text, true, null, out ret);

MessageBox.Show(ret.ToString());
}

private void Form1_Load(object sender, EventArgs e)
{

_provider = new SqlMembershipProvider();
NameValueCollection nvc = new NameValueCollection();

XmlDocument doc = new XmlDocument();

doc.LoadXml(txtConfig.Text);

foreach (XmlAttribute attr in doc.DocumentElement.Attributes)
{
nvc.Add(attr.Name, attr.Value);
}


_provider.Initialize(name, nvc );


}
}
==========================

txtconfig.Text is as below

===========
<add name="AspNetSqlMembershipProvider"
connectionStringName="LocalSqlServer" enablePasswordRetrieval="false"
enablePasswordReset="true" requiresQuestionAndAnswer="true"
applicationName="/" requiresUniqueEmail="false" passwordFormat="Hashed"
maxInvalidPasswordAttempts="5" minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="1" passwordAttemptWindow="10" />
================


If you feel necessary, I can send you my test winform project. Please feel
free to let me know if you have anything unclear.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



==================================================

Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.



Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.

==================================================



This posting is provided "AS IS" with no warranties, and confers no rights.
 
D

David Thielen

This is fantastic!!!!!!!!!!!!

One weirdness and one question. First, the weirdness. I need this for the
role manager too and you cannot put name="AspNetSqlMembershipProvider" in
private static string roleConfig = "<add
connectionStringName='MembershipSqlServer'
applicationName='/WindwardPortal'/>";

You get an exception then. Take it out and it works fine.

One problem. This requires an app.exe.config with the connection string in
it. We build the connection string on the fly in the installer so we can't
put it there. How can I pass it the connection string?

For others who may need this, the "name" passed to initialize is the name=
in the config.

--
thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm
 
S

Steven Cheng[MSFT]

Thanks for your reply Dave,

Yes, I did have investigated the connectionstring part when I tried it
previously. Unfortunately, the SqlMembershipProvider always use the
configuration setting to get the connectionstring, therefore we can not
directly supply a connectionstring on the fly. Also, if you haven't
initially created the aspnetdb.mdf file through aspnet_regsql.exe (or SQL
SMO....), and want to let the Sqlmembershipprovider automatically create it
and install those services databases, you have to use the default
SQLExpress connection string as below:

"connectionString="data source=.\SQLEXPRESS;Integrated
Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User
Instance=true"


So what I would suggest is use the default "LocalSqlServer"
connectionstring(since it is already in machine.config file). Thus, it will
locate an aspnetdb.mdf file under the "App_Data" sub directory of our
application(exe)'s directory. After create the users, you can move it to
the target place.

For the roleManager provider, I'll perform some further research, I'll also
consult some other engineers about the connectionstring issue. I'll update
you if there is any new information.


Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



This posting is provided "AS IS" with no warranties, and confers no rights.
 
D

David Thielen

We don't use the defauly when creating the database. Instead we pass all the
parameters to aspnet_regsql and we support SqlServer as well as
SqlServerExpress. We also support it being on a different computer from the
one we are running on.

If there is no app.exe.config can we somehow "write" to it these values and
Windows will then have that as our app.exe.config - either it truly does
create the app.exe.config file or it acts as though it exists?

--
thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm
 
S

Steven Cheng[MSFT]

Hello Dave,

I've discussed with some other product team engineers. I'm afraid so far
for all the SQL Server specific service providers(membership, role, profile
....), they're all tightly coupled with the <connectionString>
configuration setting, we can not supply a connectionstring on the fly with
out an app.config file. So for your scenario, my suggestion is we can
first programmtically create a app.config(customapp.exe.config) file with
the proper membership, role provider and connectionstrigns configuration
settings, after that launch the console or winform application that will
manipulate the membership/role database.

Also, I've tested the SqlRoleProvider also. As long as the configuration
setting is correctly as what we set in ASP.NET appliaction, we can call the
role management api(through SqlRoleProvider or the Roles class) correctly.

e.g
===================
private void Dump_Users()
{
MembershipUserCollection users = Membership.GetAllUsers();
txtOutput.Text += "\r\n=========Total User Count: " +
users.Count + "==========";
txtOutput.Text += "\r\n\r\n";

foreach (MembershipUser user in users)
{
txtOutput.Text += "\r\n\tUsername: " +user.UserName + "\t,
Creation Time: " + user.CreationDate;


string[] roles = Roles.GetRolesForUser(user.UserName);

txtOutput.Text += "\r\n Roles: " + string.Join(", ",roles);
}


}
================================


Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



This posting is provided "AS IS" with no warranties, and confers no rights.
 
D

David Thielen

I just got something sort-of like this to work - with no launching another app.

// we now need to put our connection string in the app.exe.config
Configuration config =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConnectionStringsSection cs =
(ConnectionStringsSection)config.GetSection("connectionStrings");
cs.ConnectionStrings.Remove("MembershipSqlServer");
cs.ConnectionStrings.Add(new ConnectionStringSettings("MembershipSqlServer",
connStr, info.ClassName));
config.Save();
// these next 2 lines are required so the config info is re-read.
ConfigurationManager.RefreshSection("connectionStrings");
ConnectionStringSettingsCollection csc =
ConfigurationManager.ConnectionStrings;

But please ask the dev team to add this to the API for the next version.
Gotta get that first user in there somehow before the ASP.NET part runs or
you can never login.

--
thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm
 
S

Steven Cheng[MSFT]

Thanks for your followup Dave,

Sure, this is really a good idea and I am also going to compose a blog
entry for a summary of this scenario.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,810
Latest member
Kassie0918

Latest Threads

Top