ASP.NET Memberships. Is it extensible? - asp.net

I add the Property "WebSite" as a property of a registered user.
<profile>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider" connectionStringName="LocalSqlServer" applicationName="membershipSampleApp" type="System.Web.Profile.SqlProfileProvider"/>
</providers>
<properties>
<add name="Website"/>
</properties>
</profile>
Where is that custom property stored in the ASPNETDB database and can I query it to, for example, find all of the users that share the same value of a custom property?
If I want this sort of capability, would I be better off to augment the USERS table with my own parallel table and join the two on UserName as the key?

Yes, you can extend Membership. Here's a long article that explains how to do it. In a nutshell,
The idea behind extending the
Membership API is as follows:
I’ll create a new ExtendedMembershipUser class that inherits all the default properties from the MembershipUser,
and then I’ll add my own custom
properties...
For storing the values in the database, it describes a:
table I added to hold the values of
the custom properties and the
accompanying stored procedures that
the new ExtendedMembershipProvider
uses.

I'm not sure how you're using the "Website" property of the profile but if you have multiple websites using the same Membership store you'd be better off specifying different application names for each site, this was how multiple webs could use the same membership store.
If "Website" is just a property for the user by all means store it in the profile. It doesn't really warrant a rewrite of the membership provider.
Also, the "Website" property would be stored in the aspnet_Profiles table (as binary and XML), this can be difficult to query though. It might make more sense to have a custom profile provider that stores the properties in plain SQL format.

The default profiles implementation sacrifices discoverability for ease of use and flexibility.
If you would like to add indexable and queryable meta data to a user, I would recommend against extending the membership provider as that is not what they are for.
An excellent and easily implemented solution is to use a table based profile provider.
see http://weblogs.asp.net/scottgu/archive/2006/01/10/435038.aspx

Related

Using both oracle db and access for one gridview

I would like to add some functionality to a gridview I have. Essentially I just want to do something similar to AutoGenerateInsert button that asp.net 2.0 does. I want the fields to push data to an AccessDataSource. The trick here though is that I want to verify some fields against an Oracle DB and even auto-populate other fields to what a user has input for a field.. As an example, my Oracle DB has personal information such as names, ages, etc. If the web-app user types in a valid name in a 'Name' field, then the field should be validated and other personal info should be auto-populated. Once all the fields are have been entered then the 'Add' button is clicked and that new record on the gridview inserts the data to an Access DB.
Any links or hints out there for accomplishing something like this?
Thanks!
-doddy
In my opinion you should store two connectionstring in web.config in aap tag
when you want to validate fields get connectionstring[0] and when you want to save field get connectionstring[1] i assume that you know how to load and save data
theres nothing complex in it.here is example
<appSettings>
<add key="dbConnection1" value="Integrated Security=SSPI;Persist Security Info=False; Initial Catalog=dbname;Data Source=servername"/>
<add key="dbConnection2" value="Datasource=servername; Initial Catalog=dbname;User ID=dbuser;Password=dbpassword" />
</appSettings>
now in code behind
public string GetconnectionString1()
{
return ConfigurationManager.AppSettings["dbconnection1"];
}
public string GetconnectionString2()
{
return ConfigurationManager.AppSettings["dbconnection2"];
}

MVC3 Entity Framework using default membership relationships

I want to create a relationship between a custom table (Websites) and the default aspnet tables related to Users.
I'm using code-first so for most FK relationships I would just do
public ModelName ModelName { get; set; }
With this, EF will automatically create the FK relationships. Very easy.
What's confusing is the most effective way to hook into the aspnet users/membership table. Do I create a new model Users that acts as an interface so that I can implement custom user code?
Is there a best way to do this that fits well into EF best practices? I basically just want to relate a user to the Websites table/model so that EF can do its thing.
"Do I create a new model Users that acts as an interface so that I can implement custom user code?"
If you want flexibility, I would say this is the way to go. This way it would be easier if you wanted to change to some sort of different Authentication DB structure in the future.
For example, have an "AppUser" Entity where the corresponding table has a foreign key to the "UserID" column of the aspnet_Membership table. This way you can simply add properties to your "AppUser" Entity instead of trying to change the MS table structure (which can be a real pain). You can still interact with the built-in MS Membership classes and functions from your MVC project using something like the MvcMembership starter Kit DLL's.
https://github.com/TroyGoode/MembershipStarterKit
Hope this helps!
This has few preconditions:
ASP.NET tables must be in the same database as your own tables
Previous precondition means that you must either create your database and tables manually (without automatic code-first generation) or you must use some custom initializer which will add non mapped ASP.NET tables as part of database recreation
If you want your model class to have relation with ASP.NET table you must model ASP.NET table as another entity. I'm not sure if you can use ASP.NET classes for that because for example MembershipUser doesn't have parameterless public constructor which is required for EF. So you will most probably need to create duplicate classes and their mappings and use these classes when referencing ASP.NET entities.

How to I delete an unrequired user profile property from web.config and the database?

I use the default ASP.NET Profile Provider which lets me define user properties in web.config.
I now no longer want to use one of these user properties. I want to delete all traces of it.
I can remove the property from the list of properties in web.config however, I suspect, the stored values for this property will still be held in the aspnet_Profile table for each user.
Is there an easy way to clean out all traces of the data for a property that's no longer used from the aspnet_Profile table?
Try deleting the property from the config and check the aspnet_Profile table. The value is probably not deleted. You can use SQL statement to clean the part you don't want or you could try using this which came across: http://snipplr.com/view/36547/aspnet-membership-provider--remove-unwanted-profile-properties/
Backup before you experiment :)

ASP.net membership add custom column

In my master page I have:
MembershipUser thisUser = Membership.GetUser();
loggedInUserID = thisUser.ProviderUserKey.ToString();
thisUser gives me access to all the fields in aspnet_Membership.
I want a new field, isSubscribed for each user. I can use an SQL query to fetch the value fine, but I want to know if there is someway to modify the membershipuser object so it retrieves this value as well, so it is accessible from:
thisUser.isSubscribed.ToString();
Thanks for any help!
you will need to add the field to the Profile Provider
A description of the Profile provider can be found here.
http://msdn.microsoft.com/en-us/library/2y3fs9xs.aspx
here is an excerpt from the article
"The ASP.NET profile feature associates information with an individual user and stores the information in a persistent format. Profiles allow you to manage user information without requiring you to create and maintain your own database. In addition, the ASP.NET profile feature makes the user information available using a strongly typed API that you can access from anywhere in your application."
Membership is for identification and authentication. It is not good practice to hack your security for the sake of a meta property.
As mentioned, Profile is the proper place to store meta data and this would obviate the need for a custom MembershipUser.
If you need sql query access to the data use the SqlTableProvider
Si Robinson gave a good answer for storing additional meta data against users without having to change the underlying schema but if you already have data stored about this user in your custom database schema, that won't quite work out.
The solution I have used is to implement my own membership provider:
http://msdn.microsoft.com/en-us/library/f1kyba5e.aspx
And then you can implement your own MembershipUser which exposes the IsSubscribed property.
This works fine with the Membership process within ASP.NET such as the login components. All you need to do is cast the object returned by GetUser() to your custom implementation and you are set!
You could use roles for this and assign users to a Subscriber role. Such as:
Roles.AddUserToRole("Bob", "Subscriber");
You're gonna have a real un-fun time querying by profile fields. With a role you will be able to enumerate users with:
Roles.GetUsersInRoles("Subscriber");
And you'll be able to add these roles to Web.Config files to control which parts of the site only Subscribers can see. Possibly better than wrapping content with a conditional based on a profile field.

Using ASP.NET SQL Membership Provider, how do I store my own per-user data?

I'm using the ASP.NET SQL Membership Provider. So, there's an aspnet_Users table that has details of each of my users. (Actually, the aspnet_Membership table seems to contain most of the actual data).
I now want to store some per-user information in my database, so I thought I'd just create a new table with a UserId (GUID) column and an FK relationship to aspnet_Users. However, I then discovered that I can't easily get access to the UserId since it's not exposed via the membership API. (I know I can access it via the ProviderUserKey, but it seems like the API is abstracting away the internal UserID in favor of the UserName, and I don't want to go too far against the grain).
So, I thought I should instead put a LoweredUserName column in my table, and create an FK relationship to aspnet_Users using that. Bzzzt. Wrong again, because while there is a unique index in aspnet_Users that includes the LoweredUserName, it also includes the ApplicationId - so in order to create my FK relationship, I'd need to have an ApplicationId column in my table too.
At first I thought: fine, I'm only dealing with a single application, so I'll just add such a column and give it a default value. Then I realised that the ApplicationId is a GUID, so it'd be a pain to do this. Not hard exactly, but until I roll out my DB I can't predict what the GUID is going to be.
I feel like I'm missing something, or going about things the wrong way. What am I supposed to do?
I think you are looking for the ProfileProvider which let's you associate any arbitrary information you wish with the user.
ASP.NET Profile Properties Overview
ADDITION If the built-in ProfileProvider will not suit your needs, then you might consider implementing your own ProfileProvider by writing a class that derives from System.Web.Profile.ProfileProvider. This would enable you to write something that avoids the serialization issues you mentioned in your comment.
Implementing a Profile Provider
ADDITION Note about the SqlMembershipProvider. You are indeed correct that the Membership classes are really keyed on username even though the schema is keyed on UserId. This is frankly one of my pet peeves about the SqlMembershipProvider classes. This actually creates problem in a multi-application environment where you want a single user store but independent application role lists.
My recommendation would be to key on UserId since it is, as you mentioned, the primary key of the aspnet_Users table and is used in all the foreign key relationships and it is a single value. If you key on LowerUsername (and ApplicationId), and the username changes, you'll need to have cascade update enabled so that the change ripples to your custom tables.
To do this, you can implement a profile provider. Its not very difficult. You will basically set up your user specific settings like this:
(web.config):
<profile enabled="true" defaultProvider="MyProvider">
<providers>
<add name="MyProvider" connectionStringName="MembershipCnnStr" applicationName="MyApp" type="System.Web.Profile.SqlProfileProvider"/>
</providers>
<properties>
<add name="EmployeeId" type="String" />
<group name="UserSettings">
<add name="IsSandboxMode" type="Boolean" defaultValue="false" />
<add name="Shortcuts" type="System.Collections.Generic.List`1[System.string]" />
</group>
</properties>
</profile>
If you're looking at adding simple data tied to your users, such as added profile properties, you should look into Personalization.
Example, if you want to store a person's mother's maiden name as a part of their profile information you can do so using this feature.
It probably isn't the right choice for complex data, but it's a start.
Write .cs file like
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
FirstNameTextBox.Text = Server.HtmlDecode(Profile.FirstName);
LastNameTextBox.Text = Server.HtmlDecode(Profile.LastName);
}
}
and web.config
<profile>
<providers>
<add name="FirstName" type="System.String"/>
<add name="LastName" type="System.String"/>
<add name="MemberId" defaultValue="0" type="System.Int32"/>
<clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>
</providers>
</profile>

Resources