I have create a create User Wizard in ASP.NET and added an additional dropdownlist Role for each user.
I have used the function ,
protected void CreateUserWizard1_CreatedUser(object sender, EventArgs e)
{
DropDownList ddlRoles = CreateUserWizard1.CreateUserStep.ContentTemplateContainer.FindControl("ddlUserRoles") as DropDownList;
Roles.AddUserToRole(CreateUserWizard1.UserName, ddlRoles.SelectedItem.ToString());
}
This creates a user and makes entry in aspnet_user, aspnet_membership table but do not create any entry in the table aspnet_UsersinRole table. I am joining these tables to get back required data but it is not giving desired result since for a user no entry exists in aspnet_UsersInRole.
Check you have roles enabled in the web.config, correct with your right connectionStringName
<roleManager defaultProvider="DefaultRoleProvider">
<providers>
<add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</roleManager>
If you want DropDownList's selected value, you want to use SelectedValue.
Roles.AddUserToRole(CreateUserWizard1.UserName, ddlRoles.SelectedValue);
FYI: Please make sure you have created Roles in aspnet_Roles table in advanced. Otherwise, no record will be added in aspnet_UsersInRole table if the specific role is not found in aspnet_Roles table.
Related
I'm working on a website in ASP.NET and unfortunately I have to use MySql to store the site's data.
I'm really struggling to get MySql work with the CreateUserWizard functionality, and I'm just losing it.
Until I defined custom properties in the Web.Config, everything was fine, and I actually managed to register some fake users. Then I wanted to add some other properties, like address, gender, and so on. I added those properties in the Web.Config like this:
Web.Config
<profile enabled="true" defaultProvider="MySqlProfileProvider">
<providers>
<clear/>
<add name="MySqlProfileProvider" autogenerateschema="True" type="MySql.Web.Profile.MySQLProfileProvider, MySql.Web, Version=6.8.3.0, Culture=neutral, PublicKeyToken=C5687FC88969C44D" conectionStringName="connMySql" applicationName="/"/>
</providers>
<properties>
<add name="Nome" type="string"/>
<add name="Cognome" type="string"/>
<add name="Sesso" type="string"/>
<add name="DataNascita" type="datetime"/>
<add name="Indirizzo" type="string"/>
<add name="Citta" type="string"/>
<add name="Provincia" type="string"/>
<add name="CAP" type="int"/>
</properties>
</profile>
Please note that my Connection String is correct, since I used it in other parts of my Web.Config and runs just fine.
Later on, in my sign up page, I wrote this code (after validating the input, of course), to update the created user.
register.aspx.cs
protected void wizard1_CreatedUser(object sender, EventArgs e)
{
ProfileCommon p = (ProfileCommon)ProfileCommon.Create(wizard1.UserName, true);
p.Nome = ((TextBox)wizard1.CreateUserStep.ContentTemplateContainer.FindControl("Nome")).Text;
p.Cognome = ((TextBox)wizard1.CreateUserStep.ContentTemplateContainer.FindControl("Cognome")).Text;
p.Sesso = ((DropDownList)wizard1.CreateUserStep.ContentTemplateContainer.FindControl("Sesso")).SelectedValue;
p.DataNascita = System.Convert.ToDateTime(((TextBox)wizard1.CreateUserStep.ContentTemplateContainer.FindControl("DataNascita")).Text);
p.Indirizzo = ((TextBox)wizard1.CreateUserStep.ContentTemplateContainer.FindControl("Indirizzo")).Text;
p.Citta = ((TextBox)wizard1.CreateUserStep.ContentTemplateContainer.FindControl("Citta")).Text;
p.Provincia = ((TextBox)wizard1.CreateUserStep.ContentTemplateContainer.FindControl("Provincia")).Text;
p.CAP = System.Convert.ToInt32(((TextBox)wizard1.CreateUserStep.ContentTemplateContainer.FindControl("CAP")).Text);
p.Save();
}
All the controls are well positioned into the .aspx page.
So, when I run the page, I can see the form and type the data in. Then my code validates the input, and if it's all correct, it creates the user and gets into the wizard1_CreatedUser function, where it stops at the p.Nome = ... part, which actually is the first instruction that makes use of the MySqlProfileProvider.
It just says Host 'Hostname' is not allowed to connect to this MySQL server BUT MySqlRoleProvider and MySqlMembershipProvider work just fine. In fact, the user is created, but my custom profile data aren't, since the code stops there.
I'm using a DB User with all the privileges.
I'm probably missing something, but I don't really know what.
Thank you.
Turns out that I needed to enable Full Trust.
Also, some files were mispositioned (they were not in the very root of the website).
I am using client application services to authenticate users for windows app. (SqlMembershipProvider) Login works fine and I can grab the user name by using the following code:
userName = System.Threading.Thread.CurrentPrincipal.Identity.Name.ToString();
I want to grab a bit more info about the user such as the email address. I have tried the following line to get the user.
MembershipUser mu = Membership.GetUser();
The above line gives me a "specified method is not supported" message. Same result if I pass in the userName as well.
Is there a way to get more detailed user info using client application services as you would in an asp.net app? If not, I wonder if I should just create my own Web Service wrapper instead?
I'm using the 4.0 Framework.
Update: A slice of the app.config file
<system.web>
<membership defaultProvider="ClientAuthenticationMembershipProvider">
<providers>
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="http://PC-03/FAAppServices/Authentication_JSON_AppService.axd" credentialsProvider="BillingFormsApplication.LoginForm, BillingFormsApplication" savePasswordHashLocally="True" />
</providers>
</membership>
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
<providers>
<add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="http://PC-03/FAAppServices/Role_JSON_AppService.axd" cacheTimeout="1209600" honorCookieExpiry="True" />
</providers>
</roleManager>
</system.web>
Update 2: Stack Trace
at System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider.GetUser(String username, Boolean userIsOnline)
at System.Web.Security.Membership.GetUser(String username, Boolean userIsOnline)
at BillingFormsApplication.MDIMain.MDIMain_Load(Object sender, EventArgs e) in C:\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.cs:line 340
SimpleMembership, as the name implies, is very simple and does not implement all of the MembershipProvider methods; just those required for MVC basic authentication and authorization. If you try to use a method that is not implemented you will get that exception. You can either create your own MembershipProvider from scratch or you can inherit from SimpleMembership and implement the methods that are not implemented.
The exception is by design
The class ClientAuthenticationMembershipProvider does not use the method GetUser.
If your app.config is configured to use ClientAuthenticationMembershipProvider, and you call Membership.GetUser, then you will always get a NotSupportedException.
ref: https://learn.microsoft.com/en-us/dotnet/api/system.web.clientservices.providers.clientformsauthenticationmembershipprovider.getuser
Following this question - aspnet_Membership IP address, I am looking to add few more fields and data regarding my users (let's say phone number, age and favorite ice cream flavor...). For that, I'll need to use more than one field and therefore, the comment field is not enough.
Is it possible to add columns to aspnet_Users or aspnet_Membership tables and bind the values entered in the registration form to these columns?
Use the ASP.NET profile provider instead. There you can add what you want (for example a picture of the user, a custom start-page or his phone-number).
Here's recommandable reading: https://web.archive.org/web/20211020111657/https://www.4guysfromrolla.com/articles/101106-1.aspx
Here's a sample from my web.config using an additional property for every user called StartPage with a SqlProfileProvider which automatically saves it in SQL-Server:
<profile defaultProvider="AspNetSqlProfileProvider">
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ErpConnectionString" applicationName="/ERP"/>
</providers>
<properties>
<add name="Startpage"/>
</properties>
</profile>
I'm reading this user setting after he has logged in:
if (User.Identity.IsAuthenticated)
{
String startPage = HttpContext.Current.Profile.GetPropertyValue("Startpage") as string;
if (!string.IsNullOrWhiteSpace(startPage))
{
Response.Redirect(startPage);
}
}
You can save the value in following way:
HttpContext.Current.Profile.SetPropertyValue("Startpage", startPage);
HttpContext.Current.Profile.Save();
I am using ASP.net membership, but I want to store additional information for client while registration instead of default columns as membership provider does, so how can I customize the dbo.aspnet_Users table and change the code so that it doesn't affect the other functionality and works fine?
Could somebody suggest me on it how can I achieve this?
Use an ASP.NET Profile-Provider.
https://web.archive.org/web/20211020111657/https://www.4guysfromrolla.com/articles/101106-1.aspx
You can store any kind of additional information even binary(images).
I've used The SqlProfileProvide myself in my currect application to let the user chose his startpage self.
Therefor i only needed to add this to the web.config:
<profile defaultProvider="AspNetSqlProfileProvider">
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="RM2ConnectionString" applicationName="/ERP"/>
</providers>
<properties>
<add name="Startpage"/>
</properties>
</profile>
And i could write this property in codebehind:
if(User.Identity.IsAuthenticated)
{
HttpContext.Current.Profile.SetPropertyValue("Startpage", startPage); //startPage is a String
HttpContext.Current.Profile.Save();
}
and read it in the following way:
if(User.Identity.IsAuthenticated)
{
Dim user = Membership.GetUser();
Dim startPage = HttpContext.Current.Profile.GetPropertyValue("Startpage") as String;
}
You can store anything you want, see the link above for further informations.
I have just switch to .Net membership provider to manage my users. I have a table relating to the Users table called UserGroupDetails. I would like to add a row to this table when Membership.CreateUser is called. If adding the user fails i would like to make sure that the record in UserGroupDetails is removed or not added and if adding the record to UserGroupDetails fails i would like the Membership.CreateUser to fail and the user to not be added.
I am not really interested in using the SqlProfileProvider and i have not found any information about overriding or modify the Membership.CreateUser to perform this additional insert.
Is it possible and if so could someone point me to a good resource on how to accomplish this?
Also, i do not want to rewrite the whole Membership.CreateUser method. Rather i would like to simple add to it. I have looked at http://msdn.microsoft.com/en-us/library/ms366730.aspx but this seems to be rebuilding the wheel.
Thanks,
D
You would build a custom provider
I've done this! I start by creating my aspnet user first. Here's what I'm doing.
1) I added this to my web.config:
<system.web>
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"
enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
applicationName="[ApplicationName]" />
</providers>
</membership>
<machineKey validationKey="[]" decryptionKey="[]" decryption="3DES" validation="SHA1" />
<connectionStrings>
<add name="ApplicationServices" connectionString="Data Source=(local);Initial Catalog=[DataBaseName];User ID=[UserName];Password=Password" providerName="System.Data.SqlClient" />
</connectionStrings>
</system.web>
2) I then use this to create my user table
var user = Membership.CreateUser(request.UserName, request.Password, request.Email);
3) Finally I grab my aspnet user id I just created and relate it in my custom user
user.ProviderUserKey.ToString();
You could create some logic to delete the aspnet user if insert into UserGroupDetails fails.
You don't need to build a custom provider. Just add your code to hookup your UserGroupDetails table after you call CreateUser.
Unfortunately, you can't use a TransactionScope to rollback the transaction if something fails because the CreateUsre will use a seperate database connection from your code, and this will require promoting the transaction to a distrivuted transaction, which is a pain to configure and setup.
The easiest solution is just check for failure of the CreateUser, and don't execute the second bit of code if it fails, and deleting the created user if your second bit fails. However, this is not foolproof as there are situations where you might have an orphaned record.
In order to do this in a single transaction, then the only solution is a custom provider, but I personally don't think it's worth the effort.
Create a custom provider that inherits membershiprovider. Override the create user method to extend the functionality. Call base.CreteUser and then add your code for adding the additional records to your custom table.
UPDATE:
Here's what your custom provider would look like
using System.Web.Security;
namespace YourNameSpace
{
public class CustomSqlMembershipProvider : SqlMembershipProvider
{
public bool CreateUser(//list of parameters)
{
bool UserCreated = false;
MembershipCreateStatus status;
//provide the required parameters
base.CreateUser(//list of parameters);
if (status == 0)//user was successfully created
{
//perform your custom code
//if success
UserCreated = true;
}
return UserCreated
}
}
}
Make sure you reference your new custom provider in your Web.config file
<membership defaultProvider="CustomMembeshipProvider">
<providers>
<clear/>
<add connectionStringName="Your connection string name" name="CustomMembeshipProvider"
type="YourNameSpace.CustomSqlMembershipProvider" />
</providers>
</membership>