I'm trying to use the MySQLRoleProvider(MySql.Web, Version=6.2.2.0) with Visual Web Developer 2008.
When trying to add a role I get an exception "Table 'test.my_aspnet_applications' doesn't exist"
if (!Roles.RoleExists("TestRole"))
{
Roles.CreateRole("TestRole");
}
Can someone tell me where I went wrong. Or tell me how to generate / find the correct database script to create the role, membership, profile ... MySql tables.
<membership defaultProvider="MySQLMembershipProvider">
<providers>
<remove name="MySQLMembershipProvider"/>
<add autogenerateschema="true" connectionStringName="LocalMySqlServer" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" applicationName="/" requiresUniqueEmail="false" passwordFormat="Clear" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="1" passwordAttemptWindow="10" passwordStrengthRegularExpression="" name="MySQLMembershipProvider" type="MySql.Web.Security.MySQLMembershipProvider, MySql.Web, Version=6.2.2.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"/>
</providers>
</membership>
<profile enabled="true" defaultProvider="MySQLProfileProvider">
<providers>
<remove name="MySQLProfileProvider"/>
<add name="MySQLProfileProvider" autogenerateschema="true" type="MySql.Web.Profile.MySQLProfileProvider, MySql.Web, Version=6.2.2.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" connectionStringName="LocalMySqlServer" applicationName="/"/>
</providers>
</profile>
<roleManager enabled="true" defaultProvider="MySQLRoleProvider">
<providers>
<remove name="MySQLRoleProvider"/>
<add autogenerateschema="true" connectionStringName="LocalMySqlServer" applicationName="/" name="MySQLRoleProvider" type="MySql.Web.Security.MySQLRoleProvider, MySql.Web, Version=6.2.2.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"/>
</providers>
</roleManager>
Have you used the ASP.Net configuration tool to switch your application's provider to the MySQL provider? I believe this is what triggers the MySQL provider to automatically generate the schema.
Follow this codeproject howto and you'll be fine.
If your database won't generate try this:
Create a custom ContextInitializer and add this to the Global.asax:
Database.SetInitializer(new CreateMySqlDatabaseIfNotExists<MyContext>());
internal class CreateMySqlDatabaseIfNotExists<TContext>: IDatabaseInitializer<TContext> where TContext : MyContext
{
public void InitializeDatabase(TContext context)
{
if (context.Database.Exists())
{
if (!context.Database.CompatibleWithModel(false))
throw new InvalidOperationException("The model has changed!");
}
else
{
CreateMySqlDatabase(context);
Seed(context);
}
}
private void CreateMySqlDatabase(TContext context)
{
try
{
context.Database.Create();
return;
}
catch (MySqlException ex)
{
// Ignore the parse exception
if (ex.Number != 1064)
{
throw;
}
}
// Manually create the metadata table
using (var connection = ((MySqlConnection) context
.Database.Connection).Clone())
using (var command = connection.CreateCommand())
{
command.CommandText =
#"
CREATE TABLE __MigrationHistory (
MigrationId mediumtext NOT NULL,
CreatedOn datetime NOT NULL,
Model mediumblob NOT NULL,
ProductVersion mediumtext NOT NULL);
ALTER TABLE __MigrationHistory
ADD PRIMARY KEY (MigrationId(255));
INSERT INTO __MigrationHistory (
MigrationId,
CreatedOn,
Model,
ProductVersion)
VALUES (
'InitialCreate',
#CreatedOn,
#Model,
#ProductVersion);
";
command.Parameters.AddWithValue(
"#Model",
GetModel(context));
command.Parameters.AddWithValue(
"#ProductVersion",
GetProductVersion());
command.Parameters.AddWithValue(
"#CreatedOn",
DateTime.Now);
connection.Open();
command.ExecuteNonQuery();
}
}
private byte[] GetModel(TContext context)
{
using (var memoryStream = new MemoryStream())
{
using (var gzipStream = new GZipStream(
memoryStream,
CompressionMode.Compress))
using (var xmlWriter = XmlWriter.Create(
gzipStream,
new XmlWriterSettings {Indent = true}))
{
EdmxWriter.WriteEdmx(context, xmlWriter);
}
return memoryStream.ToArray();
}
}
private string GetProductVersion()
{
return typeof (DbContext).Assembly
.GetCustomAttributes(false)
.OfType<AssemblyInformationalVersionAttribute>()
.Single()
.InformationalVersion;
}
protected void Seed(TContext context)
{ // ...
context.SaveChanges();
}
}
Related
Hi I want Change Text of error requiresUniqueEmail
i set requiresUniqueEmail provider to true
and massage default is The e-mail address that you entered is already in use. Please enter a different e-mail address
and i want change that text
my provide is
<add name="MemberShipProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="******"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
applicationName="/"
requiresUniqueEmail="true"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="5"
minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10"
passwordStrengthRegularExpression="" />
I'm not positive this will work with SqlMembershipProvider but I've used this with the built-in sign up control:
protected void RegisterUser_CreateUserError(object sender, CreateUserErrorEventArgs e)
{
switch(e.CreateUserError)
{
case MembershipCreateStatus.DuplicateUserName:
RegisterUser.DuplicateUserNameErrorMessage = "No can do!";
break;
// other cases.
default:
break;
}
}
How would I delete / clear / wipe / overwrite a log file being written through EL6 logging. I am using a logwriter instance to write to a log file that needs to be overwritten every cycle as my program runs in a continuous loop. I will be writing values then overwriting as new values come through.
There may be other/better ways to attack this, but I was able to clear the log file by temporarily repointing the static LogWriter to a temp file, clearing the log with simple File I/O, and then reconnecting the original LogWriter.
I wrote up a simple C# Console App to demonstrate. There are some hard-coded references to the log file configuration in App.config that could probably be cleaned up by using the ConfigurationSourceBuilder, but hopefully this can get you started.
Programs.cs:
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using System;
using System.Diagnostics;
using System.IO;
namespace LogFileClearance
{
public static class Marker
{
public static LogWriter customLogWriter { get; set; }
}
class Program
{
private static object _syncEventId = new object();
private static object locker = new object();
private static int _eventId = 0;
private const string INFO_CATEGORY = "All Events";
static void Main( string [] args )
{
InitializeLogger();
Console.WriteLine( "Enter some input, <Enter> or q to quit, c to clear the log file" );
string input = Console.ReadLine().ToUpper();
while ( ! string.IsNullOrEmpty(input) && input != "Q" )
{
Console.WriteLine( "You entered {0}", input );
if ( input == "C" )
{
ClearLog();
}
else
{
WriteLog( input );
}
Console.WriteLine( "Enter some input, <Enter> or q to quit, c to clear the log file" );
input = Console.ReadLine().ToUpper();
}
}
private static int GetNextEventId()
{
lock ( _syncEventId )
{
return _eventId++;
}
}
public static void InitializeLogger()
{
try
{
lock ( locker )
{
if ( Marker.customLogWriter == null )
{
var writer = new LogWriterFactory().Create();
Logger.SetLogWriter( writer, false );
}
else
{
Logger.SetLogWriter( Marker.customLogWriter, false );
}
}
}
catch ( Exception ex )
{
Debug.WriteLine( "An error occurred in InitializeLogger: " + ex.Message );
}
}
static internal void WriteLog( string message )
{
LogEntry logEntry = new LogEntry();
logEntry.EventId = GetNextEventId();
logEntry.Severity = TraceEventType.Information;
logEntry.Priority = 2;
logEntry.Message = message;
logEntry.Categories.Add( INFO_CATEGORY );
// Always attach the version and username to the log message.
// The writeLog stored procedure will parse these fields.
Logger.Write( logEntry );
}
static internal void ClearLog()
{
string originalFileName = string.Format(#"C:\Logs\LogFileClearance.log");
string tempFileName = originalFileName.Replace( ".log", "(TEMP).log" );
var textFormatter = new FormatterBuilder()
.TextFormatterNamed( "Custom Timestamped Text Formatter" )
.UsingTemplate("{timestamp(local:MM/dd/yy hh:mm:ss.fff tt)} tid={win32ThreadId}: {message}");
#region Set the Logging LogWriter to use the temp file
var builder = new ConfigurationSourceBuilder();
builder.ConfigureLogging()
.LogToCategoryNamed( INFO_CATEGORY ).WithOptions.SetAsDefaultCategory()
.SendTo.FlatFile( "Flat File Trace Listener" )
.ToFile(tempFileName);
using ( DictionaryConfigurationSource configSource = new DictionaryConfigurationSource() )
{
builder.UpdateConfigurationWithReplace(configSource);
Marker.customLogWriter = new LogWriterFactory(configSource).Create();
}
InitializeLogger();
#endregion
#region Clear the original log file
if ( File.Exists(originalFileName) )
{
File.WriteAllText(originalFileName, string.Empty);
}
#endregion
#region Re-connect the original file to the log writer
builder = new ConfigurationSourceBuilder();
builder.ConfigureLogging()
.WithOptions.DoNotRevertImpersonation()
.LogToCategoryNamed( INFO_CATEGORY ).WithOptions.SetAsDefaultCategory()
.SendTo.RollingFile("Rolling Flat File Trace Listener")
.RollAfterSize(1000)
.FormatWith(textFormatter).WithHeader("").WithFooter("")
.ToFile(originalFileName);
using ( DictionaryConfigurationSource configSource = new DictionaryConfigurationSource() )
{
builder.UpdateConfigurationWithReplace( configSource );
Marker.customLogWriter = new LogWriterFactory( configSource ).Create();
}
InitializeLogger();
#endregion
}
}
}
App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<loggingConfiguration name="Logging Application Block" tracingEnabled="true" defaultCategory="" logWarningsWhenNoCategoriesMatch="true">
<listeners>
<add fileName="C:\Logs\LogFileClearance.log" footer="" formatter="Timestamped Text Formatter"
header="" rollFileExistsBehavior="Increment"
rollInterval="None" rollSizeKB="1000" timeStampPattern="yyyy-MM-dd"
listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" traceOutputOptions="None" filter="All" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="Log File Listener" />
</listeners>
<formatters>
<add template="{timestamp(local:MM/dd/yy hh:mm:ss tt)} tid={win32ThreadId}: {message}" type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="Timestamped Text Formatter" />
</formatters>
<categorySources>
<add switchValue="Information" name="All Events">
<listeners>
<add name="Log File Listener" />
</listeners>
</add>
<add switchValue="Error" name="Logging Errors & Warnings">
<listeners>
<add name="Log File Listener" />
</listeners>
</add>
</categorySources>
<specialSources>
<allEvents switchValue="Information" name="All Events" />
<notProcessed switchValue="All" name="Unprocessed Category" />
<errors switchValue="All" name="Logging Errors & Warnings" />
</specialSources>
</loggingConfiguration>
</configuration>
I am trying to Initialize SQL Membership Provider by code and everything is working fine in the first request only!. When the code below executes again (after refreshing the page for example) I get the following error:
The attribute 'connectionStringName' is missing or empty.
Page Load Code:
MembershipSection membershipSection = (MembershipSection)ConfigurationManager.GetSection("system.web/membership");
string sqlProviderName = "AspNetSqlMembershipProvider";
NameValueCollection providerConfig;
providerConfig = membershipSection.Providers[sqlProviderName].Parameters; // returning empty list in the second request
var _SqlProvider = new SqlMembershipProvider();
_SqlProvider.Initialize(sqlProviderName, providerConfig);
Web.config:
<membership defaultProvider="AspNetSqlMembershipProvider">
<providers>
<clear />
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ConnectionString" enablePasswordRetrieval="true" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" passwordFormat="Encrypted" maxInvalidPasswordAttempts="5" passwordAttemptWindow="10" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" applicationName="/" />
</providers>
</membership>
Any Advice?
how about just keep your data/connectionstring/obj at static level (as like singleton)?
it's not like connectionstring is going to be change throughout the web instance, does it?
static string/dataType _DataToBeRead1timeOnly = null;
static string/dataType DataToBeRead1timeOnly
{
get {
if (_DataToBeRead1timeOnly == null) { _DataToBeRead1timeOnly = .... }
return _DataToBeRead1timeOnly;
}
}
I have the following code, which I want to use to modify the ProfileBase connectionString:
ProfileBase profile = ProfileBase.Create(username);
string _connectionString = (_DataModel.Connection as System.Data.EntityClient.EntityConnection).StoreConnection.ConnectionString;
FieldInfo connectionStringField = profile.Providers["MySqlProfileProvider"].GetType().BaseType.GetField("_sqlConnectionString", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
connectionStringField.SetValue(profile.Providers["MySqlProfileProvider"], _connectionString);
profile["FirstName"] = firstName;
profile["Surname"] = surname;
profile.Save();
First of all the connectionStringField always comes back as null, however I can see that profile.Providers does contain MySqlProfileProvider. This is specified within my Web.Config:
<profile defaultProvider="MySqlProfileProvider">
<providers>
<clear/>
<add name="MySqlProfileProvider" connectionStringName="MyApp" applicationName="MyApp" type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</providers>
<properties>
<add allowAnonymous="false" defaultValue="" name="FirstName" readOnly="false" serializeAs="String" type="System.String"/>
<add allowAnonymous="false" defaultValue="" name="Surname" readOnly="false" serializeAs="String" type="System.String"/>
</properties>
</profile>
My question is how come connectionStringField is coming back as null? Does this mean I cannot modify the connection string like I normally would with a custom MembershipProvider by overriding its Initialize method?
You went one too many basetypes down:
.Providers["MySqlProfileProvider"].GetType()**.BaseType**.GetField
.Providers["MySqlProfileProvider"].GetType().GetField
The following code should work:
string _connectionString = (_DataModel.Connection as System.Data.EntityClient.EntityConnection).StoreConnection.ConnectionString;
Type type = profile.Providers["MySqlProfileProvider"].GetType();
FieldInfo connectionStringField = type.GetField("_sqlConnectionString", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
connectionStringField.SetValue(profile.Providers["MySqlProfileProvider"], _connectionString);
I have an asp.net web app that uses forms-based authentication, a SqlMembershipProvider (using an encrypted password format), and a SqlRoleProvider. I need to know if it's possible to administer the users (create new users, assign them to roles, etc.) from a windows application - the powers that be don't want any administrative functionality in the web app itself.
Here is the membership provider definition from web.config:
<membership defaultProvider="MyProvider">
<providers>
<add name="MyProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="MyConnectionString"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
applicationName="/MyWebApp"
requiresUniqueEmail="true"
passwordFormat="Encrypted"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="1"
passwordAttemptWindow="10"
passwordStrengthRegularExpression=""/>
</providers>
</membership>
And the role manager definition:
<roleManager enabled="true" defaultProvider="MyRoleManager">
<providers>
<add name="MyRoleManager"
type="System.Web.Security.SqlRoleProvider"
connectionStringName="MyConnectionString"
applicationName="/MyWebApp" />
</providers>
</roleManager>
And here is the machineKey definition (necessary to be able to use encrypted passwords):
<machineKey
validationKey="BC50A82A6AF6A015C34C7946D29B817C00F04D2AB10BC2128D1E2433D0E365E426E57337CECAE9A0681A2C736B9779B42F75D60F09F142C60E9E0E8F9840DB46"
decryptionKey="122035576C5476DCD8F3611954C837CDA5FE33BCDBBF23F7"
validation="SHA1"
decryption="AES"/>
So, obviously, I have a Sql Server database that contains the users and roles for the web app. I'd like to create a separate windows app that references the web app assembly, and use the configured MembershipProvider, RoleProvider, and machineKey to create users, assign users to roles, etc. If that's not possible, I can duplicate the configuration settings from web.config within the windows app. But I don't know how to do this either.
Am I way out of line thinking that this is possible? I've tried googling for a solution, but the signal-to-noise ratio is really bad.
Some options:
You could use the Web Site
Administration Tool, which isn't
Windows-Forms-based, but isn't part
of your Web app, either. It comes
with Visual Studio and can be
accessed by clicking the ASP.NET
Configuration icon in the Solution
Explorer.
It's possible to directly manipulate
the provider database used by a
SqlMembershipProvider from a Windows
Forms app, but you might have to be
careful not to break things.
If you were to create a custom
membership provider, you'd be in
control of how membership and role
data is persisted. If you did that
you could create a reusable library
that could be used in the Web app and
a Windows Forms app, too.
I don't think trying to use a SqlMembershipProvider from a Windows Forms app is a practical approach.
I've come up with a solution, based on the other answers (who both got +1), and some other sites out there.
First, I created Application Config file (app.config). It mirrors exactly what is found in web.config from the web app, with the exception of how the connection string was handled:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="connectionStrings" type="System.Configuration.ConnectionStringsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="MyConnectionString"
connectionString ="SERVER=abc;UID=def;PWD=hij;Initial Catalog=klm;MultipleActiveResultsets=True"/>
</connectionStrings>
<system.web>
<membership defaultProvider="MySqlMembershipProvider">
<providers>
<add name="MySqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="MyConnectionString"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
applicationName="/MyWebApp"
requiresUniqueEmail="true"
passwordFormat="Encrypted"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="1"
passwordAttemptWindow="10"
passwordStrengthRegularExpression=""/>
</providers>
</membership>
<roleManager enabled="true" defaultProvider="MySqlRoleManager">
<providers>
<add name="MySqlRoleManager"
type="System.Web.Security.SqlRoleProvider"
connectionStringName="MyConnectionString"
applicationName="/MyWebApp" />
</providers>
</roleManager>
<machineKey
validationKey="BC50A82A6AF6A015C34C7946D29B817C00F04D2AB10BC2128D1E2433D0E365E426E57337CECAE9A0681A2C736B9779B42F75D60F09F142C60E9E0E8F9840DB46"
decryptionKey="122035576C5476DCD8F3611954C837CDA5FE33BCDBBF23F7"
validation="SHA1"
decryption="AES"/>
</system.web>
</configuration>
Then I created a helper class that provides access to two singletons: a MembershipProvider and a RoleProvider. This turned out to be easier than I thought, once I knew how to do it:
using System.Configuration;
using System.Reflection;
using System.Web.Security;
namespace WebAdminViaWindows
{
internal static class Provider
{
private static readonly string assemblyFilePath = Assembly.GetExecutingAssembly().Location;
static Provider()
{
Membership = CreateMembershipProvider();
Role = CreateRoleProvider();
}
public static MembershipProvider Membership { get; private set; }
public static RoleProvider Role { get; private set; }
private static MembershipProvider CreateMembershipProvider()
{
var config = ConfigurationManager.OpenExeConfiguration(assemblyFilePath);
var systemWebGroup = config.SectionGroups["system.web"];
if (systemWebGroup == null)
{
throw new ConfigurationErrorsException("system.web group not found in configuration");
}
var membershipSection = systemWebGroup.Sections["membership"];
if (membershipSection == null)
{
throw new ConfigurationErrorsException("membership section not found in system.web group");
}
var defaultProviderProperty = membershipSection.ElementInformation.Properties["defaultProvider"];
if (defaultProviderProperty == null)
{
throw new ConfigurationErrorsException("defaultProvider property not found in membership section");
}
var defaultProviderName = defaultProviderProperty.Value as string;
if (defaultProviderName == null)
{
throw new ConfigurationErrorsException("defaultProvider property is not a string value");
}
var providersProperty = membershipSection.ElementInformation.Properties["providers"];
if (providersProperty == null)
{
throw new ConfigurationErrorsException("providers property not found in membership section");
}
var providerCollection = providersProperty.Value as ProviderSettingsCollection;
if (providerCollection == null)
{
throw new ConfigurationErrorsException("providers property is not an instance of ProviderSettingsCollection");
}
ProviderSettings membershipProviderSettings = null;
foreach (ProviderSettings providerSetting in providerCollection)
{
if (providerSetting.Name == defaultProviderName)
{
membershipProviderSettings = providerSetting;
}
}
if (membershipProviderSettings == null)
{
if (providerCollection.Count > 0)
{
membershipProviderSettings = providerCollection[0];
}
else
{
throw new ConfigurationErrorsException("No providers found in configuration");
}
}
var provider = new SqlMembershipProvider();
provider.Initialize("MySqlMembershipProvider", membershipProviderSettings.Parameters);
return provider;
}
private static RoleProvider CreateRoleProvider()
{
var config = ConfigurationManager.OpenExeConfiguration(assemblyFilePath);
var systemWebGroup = config.SectionGroups["system.web"];
if (systemWebGroup == null)
{
throw new ConfigurationErrorsException("system.web group not found in configuration");
}
var roleManagerSection = systemWebGroup.Sections["roleManager"];
if (roleManagerSection == null)
{
throw new ConfigurationErrorsException("roleManager section not found in system.web group");
}
var defaultProviderProperty = roleManagerSection.ElementInformation.Properties["defaultProvider"];
if (defaultProviderProperty == null)
{
throw new ConfigurationErrorsException("defaultProvider property not found in roleManager section");
}
var defaultProviderName = defaultProviderProperty.Value as string;
if (defaultProviderName == null)
{
throw new ConfigurationErrorsException("defaultProvider property is not a string value");
}
var providersProperty = roleManagerSection.ElementInformation.Properties["providers"];
if (providersProperty == null)
{
throw new ConfigurationErrorsException("providers property not found in roleManagerSection section");
}
var providerCollection = providersProperty.Value as ProviderSettingsCollection;
if (providerCollection == null)
{
throw new ConfigurationErrorsException("providers property is not an instance of ProviderSettingsCollection");
}
ProviderSettings roleProviderSettings = null;
foreach (ProviderSettings providerSetting in providerCollection)
{
if (providerSetting.Name == defaultProviderName)
{
roleProviderSettings = providerSetting;
}
}
if (roleProviderSettings == null)
{
if (providerCollection.Count > 0)
{
roleProviderSettings = providerCollection[0];
}
else
{
throw new ConfigurationErrorsException("No providers found in configuration");
}
}
var provider = new SqlRoleProvider();
provider.Initialize("MySqlRoleManager", roleProviderSettings.Parameters);
return provider;
}
}
}
At this point all that's needed is to access the Membership and Role properties of the Provider class. As an example, the following prints out the first 10 users and their roles:
int total;
foreach (MembershipUser user in Provider.Membership.GetAllUsers(0, 10, out total))
{
var sb = new StringBuilder();
sb.AppendLine(user.UserName);
foreach (var role in Provider.Role.GetRolesForUser(user.UserName))
{
sb.AppendLine("\t" + role);
}
Console.WriteLine(sb.ToString());
}
I'm not sure what "best-practice" would be here, but a simple way that should work is this.
Make a new windows app
Add an Application Config file
(app.config)
Copy the appropriate settings into
the app.config (settings from above
^)
Add a reference to System.Web
And copy the code from your web app
that uses the above settings to
connect to the database
That should do what you want.