How to get profile info by userId in asp.net mvc 3? - asp.net

I want to implement user profile, so other users will be able to see it.
How can I get profile info about a particular user by it's id in asp.net mvc3??

This is (in a nutshell) how you would implement the default profile provider.
In your web.config, add
<profile>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider"
type="System.Web.Profile.SqlProfileProvider"
connectionStringName="ApplicationServices"
<!--same connection string as the membership provider-->
applicationName="/"/>
</providers>
<properties>
<add name="FirstName" type="string"/>
<add name="LastName" type="string"/>
<!--...or whatever profile properties you want/need-->
</properties>
</profile>
Then you can assign values to the profile properties
ProfileBase profile = ProfileBase.Create(userName);
profile["FirstName"] = "John";
profile["LastName"] = "Smith";
And read the values
string firstName;
string lastName;
ProfileBase profile = ProfileBase.Create(userName);
firstName = profile["FirstName"] as string,
lastName = profile["LastName"] as string,

Related

When finished create user using (CreateUserWizard control) add profile information in the same process

When I try this code it's give this error message
This property cannot be set for anonymous users.
protected void CreateUserWizard1_CreatedUser(object sender, EventArgs e)
{
Roles.AddUserToRole((sender as CreateUserWizard).UserName, "Admin");
Control ctrl = CreateUserWizard1.CreateUserStep.ContentTemplateContainer;
TextBox txtAdminAddress= (TextBox)ctrl.FindControl("txtAdminAddress");
TextBox txtAdminCountry= (TextBox)ctrl.FindControl("txtAdminCountry");
TextBox txtAdminCity= (TextBox)ctrl.FindControl("txtAdminCity");
HttpContext.Current.Profile.GetProfileGroup("AdminGroup").SetPropertyValue("AdminAddress", txtAdminAddress.Text);
HttpContext.Current.Profile.GetProfileGroup("AdminGroup").SetPropertyValue("AdminCountry", txtAdminCountry.Text);
HttpContext.Current.Profile.GetProfileGroup("AdminGroup").SetPropertyValue("AdminCity", txtAdminCity.Text);
HttpContext.Current.Profile.Save();
}
Config:
<profile defaultProvider="AspNetSqlProfileProvider">
<properties>
<group name="AdminGroup">
<add name="AdminAddress" type="System.String"/>
<add name="AdminCountry" type="System.String"/>
<add name="AdminCity" type="System.String"/>
</group>
</properties>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="MyConnectionString" applicationName="/"/>
</providers>
</profile>
After creating the User, You need to fetch the profile of recently created user to start updating values. Since No profile is Loaded, it won't allow to set these values for anonymous users.
string strUsername = (sender as CreateUserWizard).UserName;
ProfileCommon p = Profile.GetProfile(strUsername);
//update the field and save
p.AdminAddress= txtAdminAddress.Text;
p.Save();
The ProfileBase object (provided by the Page.Profile property) includes a useful GetProfile() function that retrieves, by user name, the profile information for a specific user.
GetProfile() returns a ProfileCommon object.
[ Note: The profile properties set in Config file doesn't allow setting values for Anonymous users. If you want to allow this for anonymous users also use:
<add name="AdminAddress" type="System.String" allowAnonymous="true"/>
]

No access to user profiles

I am using mySQL as ny db and have all the asp membership configuration in place.
I have set additional profile proerties in my web.comfig file as shown below;
<profile defaultProvider="MySQLProfileProvider">
<providers>
<add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
<remove name="MySQLProfileProvider" />
<add name="MySQLProfileProvider" type="MySql.Web.Profile.MySQLProfileProvider, MySql.Web, Version=6.6.3.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" applicationName="/" description="" connectionStringName="LocalMySqlServer" writeExceptionsToEventLog="False" autogenerateschema="True" enableExpireCallback="False" />
</providers>
<properties>
<add name="AccountConfirmationId" type="System.String" />
<add name="FullName" type="System.String" />
<add name="CompanyName" type="System.String" />
<add name="CompanyLocationName" type="System.String" />
</properties>
</profile>
My first question is where are the profile values actually stored? There is no additional columns created in my membership profile table.
Secondly, I am using the method outlined below to store the entered values in the registration process into the profile, from the "Next" button click event.
Protected Sub RegisterUser_NextButtonClick(sender As Object, e As WizardNavigationEventArgs) Handles RegisterUser.NextButtonClick
'set Profile object and give it its property values
Dim userProfile As ProfileCommon = TryCast(ProfileCommon.Create(RegisterUser.UserName), ProfileCommon)
userProfile.AccountConfirmationId = Guid.NewGuid().ToString()
userProfile.SetPropertyValue("FullName", FullName.Text)
userProfile.SetPropertyValue("FullName", CompanyName.Text)
userProfile.SetPropertyValue("FullName", CompanyLocationName.Text)
userProfile.Save()
Session("rolerequest") = ddlRegisterAs.SelectedItem.ToString()
Session("acctconfid") = userProfile.AccountConfirmationId
Session("completename") = FullName.Text
Session("compname") = CompanyName.Text
Session("compnamelocation") = CompanyLocationName.Text
End Sub
I try to retrieve the profile values on my admin user management page with the following method ( triggered by username selection from a dropdownlist)
Protected Sub ddlSiteUsers_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ddlSiteUsers.SelectedIndexChanged
Try
Dim userProfile As ProfileCommon = Profile.GetProfile(ddlSiteUsers.SelectedItem.ToString())
tbProfileUserFullname.Text = userProfile.GetPropertyValue("FullName").ToString()
tbProfileCompany.Text = userProfile.GetPropertyValue("CompanyName").ToString()
tbProfileCompLoc.Text = userProfile.GetPropertyValue("CompanyLocationName").ToString()
Catch ex As Exception
lblSiteUserErrMessage.Text = "User profile not found... " & ex.Message.ToString()
lblSiteUserErrMessage.Visible = True
End Try
End Sub
All values come up as empty strings. Any help appreciated.
I am using a website project not a web application.
To answer your first question, the property names and values are serialized and stored in the existing table columns. See this blog post for more details:
How ASP.NET Profile Properties are serialized in the database using Sql Profile Provider
These are the (auto-generated) columns in the profile table for my web app:
[UserId] [uniqueidentifier] NOT NULL,
[PropertyNames] [nvarchar](4000) NOT NULL,
[PropertyValueStrings] [nvarchar](4000) NOT NULL,
[PropertyValueBinary] [image] NOT NULL,
[LastUpdatedDate] [datetime] NOT NULL,
In short, the profile properties are not directly accessible for querying outside of the Profile provider. For that reason I have seen several recommendations to not use the default Profile provider and instead store User details in a separate UserDetails table. I ended up adding columns directly to the Users table, which has so far worked fine for me, but may not be the best choice for some applications.

ASP.Net Using the Membership.CreateUser Method

I'm having issues using the membership.createuser method. My code is below, I get a null exception as runtime. Any help is greatly appreciated.
Dim username As String = userNameTxt.Text
Dim password As String = passwordTxt.Text
Dim email As String = emailTxt.Text
Dim status As New MembershipCreateStatus
Dim blank As String = ""
Dim provider As MembershipProvider
Dim providerUserKey As New System.Object
Dim user As MembershipUser
user = provider.CreateUser(username, password, email, blank, blank, True, providerUserKey, status)
you need concrete implementation of MembershipProvider abstract class
you can either create your own or use existing one. You also need to set it in web.config:
<connectionStrings>
<add name="MySqlConnection" connectionString="Data Source=MySqlServer;Initial Catalog=aspnetdb;Integrated Security=SSPI;" />
</connectionStrings>
<system.web>
...
<membership defaultProvider="SqlProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add
name="SqlProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="MySqlConnection"
applicationName="MyApplication"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
requiresUniqueEmail="true"
passwordFormat="Hashed" />
</providers>
</membership>
http://msdn.microsoft.com/en-us/library/ff648345.aspx
then you can use Membership.CreateUser, no need to create instance, it's static
it has also a property for default membership provider set in web.config: Membership.Provider
Use the shared methods on the Membership class. You will have to configure the membership provider to use in your web.config file.
Then it's simply:
Membership.CreateUser(username, password, email, blank, blank, True, providerUserKey, status)
For details on how to configure your membership provider, refer to msdn Memberhip doc
Dim provider As MembershipProvider
then
provider.CreateUser(..
provider is null as you haven't actually created a new instance
you should be using
System.Web.Security.Membership.CreateUser

Default SqlRoleProvider in backend code

How do I access the default SqlProvider in a DAL? I've only ever done this before from webforms.
With the following
using System.Web.Security;
....
SqlRoleProvider roleProvider = new SqlRoleProvider();
string[] roles = roleProvider.GetAllRoles(); //for example to get all role names
EDIT
To configure your application to use the SqlRoleProvider you'll need to add the following under the <system.web> section of your web.config file.
<roleManager enabled="true" defaultProvider="SqlRoleManager">
<providers>
<add name="SqlRoleManager"
type="System.Web.Security.SqlRoleProvider"
connectionStringName="MyConnectionStringName" //change this to the name of your connection string
applicationName="MyApplication" />
</providers>
</roleManager>

How to manually verify a user against the ASP.NET memberhip database?

I would like to know how I can verify a user's credential against an existing asp.net membership database. The short story is that we want provide single sign on access.
So what I've done is to connect directly to the membership database and tried to run a sql query against the aspnet_Membership table:
private bool CanLogin(string userName, string password)
{
// Check DB to see if the credential is correct
try
{
string passwordHash = FormsAuthentication.HashPasswordForStoringInConfigFile(password, "SHA1");
string sql = string.Format("select 1 from aspnet_Users a inner join aspnet_Membership b on a.UserId = b.UserId and a.applicationid = b.applicationid where a.username = '{0}' and b.password='{1}'", userName.ToLowerInvariant(), passwordHash);
using (SqlConnection sqlConn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString))
using (SqlCommand sqlCmd = new SqlCommand(sql, sqlConn))
{
sqlConn.Open();
int count = sqlCmd.ExecuteNonQuery();
return count == 1;
}
}
catch (Exception ex)
{
return false;
}
}
The problem is the password value, does anyone know how the password it is hashed?
if you have two asp.net apps on the same IIS server, you can do SSO like this. I asked this question and answered it myself.
here
Once you have both apps pointing at your asp_membership database by placing the following in the system.web section of your web config
<authentication mode="Forms" />
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="membership"
applicationName="/"
/>
</providers>
</membership>
<roleManager enabled="true" />
make sure both have the same applicationname property set.
I was using IIS 6 so I configured it to autogenerate a machine key for both applications. Because both of these applications live on the same machine the key would be identical, this is the critical part to making the SSO work. After setting up IIS the following was added to my web.config
<machineKey decryptionKey="AutoGenerate" validation="SHA1" validationKey="AutoGenerate" />
That was all there was to it. Once that was done I could log into app1 and then browse to app2 and keep my security credentials.
The problem is the password value,
does anyone know how the password it
is hashed?
Yes - you do! Check your web.config file for something like this:
<membership defaultProvider="MembershipSqlProvider"
userIsOnlineTimeWindow="15">
<providers>
<add name="MembershipSqlProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web,
Version=1.2.3400.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
PasswordFormat="Hashed" />
</providers>
</membership>
The PasswordFormat is what you are looking for. It can have the following three values:
Clear
Encrypted
Hashed
And, Microsoft sets the default value to Hashed for PasswordFormat.
Why don't check it automatically via System.Web.Security.Membership.ValidateUser() ?
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<membership defaultProvider="MyMembershipProvider">
<providers>
<clear />
<add name="MyMembershipProvider" type="MyApplication.MyMembershipProvider" connectionStringName="MyConnString" />
</providers>
</membership>
</system.web>
</configuration>

Resources