Reputation: 2941
I am using the Profile feature of ASP.NET in a website. Updating a profile is working weirdly! A user can't update his/her own profile, neither the web site user nor the administrator, but, the administrator is able to update profiles of other users.
In the backend, after Profile's save() is called, SQL Server traces show that aspnet_Profile_SetProperties stored procedure is called twice. First, with new values, then, with old values. The second execution is done after page unload. My code has nothing to do with transactions.
Why is it working so weirdly?
Could there be an issue with aspnet_regsql's installation as I have installed uninstalled and again installed it!?
Code
web.config
<authentication mode="Forms">
<forms name="FormsAuthentication" loginUrl="~/Login.aspx" defaultUrl="~/Login.aspx" timeout="20"/>
</authentication>
<membership defaultProvider="CustSqlMembershipProvider">
<providers>
<add connectionStringName="connString" applicationName="/space_online" minRequiredPasswordLength="5" minRequiredNonalphanumericCharacters="0" name="CustSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider"/>
</providers>
</membership>
<roleManager enabled="true" defaultProvider="CustSqlRoleProvider">
<providers>
<add connectionStringName="connString" applicationName="/space_online" name="CustSqlRoleProvider" type="System.Web.Security.SqlRoleProvider"/>
</providers>
</roleManager>
<anonymousIdentification cookieless="AutoDetect" enabled="true"/>
<profile defaultProvider="CustSqlProfileProvider" enabled="true">
<providers>
<add name="CustSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="connString" applicationName="/space_online"/>
</providers>
<properties>
<add name="FirstName" type="System.String"/>
<add name="LastName" type="System.String"/>
<add name="Email" type="System.String"/>
<group name="Address">
<add name="Street" type="System.String"/>
<add name="City" type="System.String"/>
<add name="PostalCode" type="System.String"/>
</group>
<group name="Contact">
<add name="Phone" type="System.String"/>
<add name="Mobile" type="System.String"/>
<add name="Fax" type="System.String"/>
</group>
<add name="ShoppingCart" type="psb.website.BLL.Store.ShoppingCart" serializeAs="Binary" allowAnonymous="true"/>
</properties>
</profile>
Code behind
private void UpdateProfile(ProfileCommon myprofile)
{
myprofile.FirstName = tbFirstName.Text.Trim();
myprofile.LastName = tbLastName.Text.Trim();
myprofile.Email = tbEmail.Text.Trim();
myprofile.Address.Street = tbStreetPhysical.Text.Trim();
myprofile.Address.City = tbCity.Text.Trim();
myprofile.Address.PostalCode = tbPostalCode.Text.Trim();
myprofile.Contact.Phone = tbPhone1.Text.Trim();
myprofile.Contact.Mobile = tbMobile.Text.Trim();
myprofile.Save();
}
private ProfileCommon GetProfile()
{
ProfileCommon profile = this.Profile;
if (Request.QueryString["UserName"] != null && HttpContext.Current.User.IsInRole("Admin"))
profile = this.Profile.GetProfile(Request.QueryString["UserName"].ToString());
else
profile = this.Profile.GetProfile(HttpContext.Current.User.Identity.Name);
return profile;
}
protected void tbUpdateProfile_Click(object sender, ImageClickEventArgs e)
{
UpdateProfile(GetProfile());
}
Upvotes: 7
Views: 4332
Reputation: 138841
The profile is by default automatically saved at the end of the execution of an ASP.NET page, see the profile Element (ASP.NET Settings Schema) documentation on this. This explains the second "mysterious" save that you observe.
You can try to change automaticSaveEnabled
to false.
Upvotes: 5
Reputation: 4569
You may need to clear the default provider in your web.config. Like this:
<profile defaultProvider="CustSqlProfileProvider" enabled="true">
<providers>
<clear /><!-- here -->
<add name="CustSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="connString" applicationName="/space_online"/>
</providers>
<properties>
<...>
</properties>
</profile>
Here is a good explanation for this: Removing existing profile providers
And here is another good site: http://odetocode.com/articles/440.aspx
Upvotes: 0
Reputation: 4112
Access to ProfileCommon should be done through HttpContext.Current.Profile as that is a reference to the current user's profile (logged in or anonymous) and you don't need to explicitly call Save. Try this:
private void UpdateProfile()
{
var myprofile = HttpContext.Current.Profile as ProfileCommon;
if (profile == null) {
throw new InvalidOperationException("HttpContext.Current.Profile is not of type ProfileCommon for some reason!");
}
myprofile.FirstName = tbFirstName.Text.Trim();
myprofile.LastName = tbLastName.Text.Trim();
myprofile.Email = tbEmail.Text.Trim();
myprofile.Address.Street = tbStreetPhysical.Text.Trim();
myprofile.Address.City = tbCity.Text.Trim();
myprofile.Address.PostalCode = tbPostalCode.Text.Trim();
myprofile.Contact.Phone = tbPhone1.Text.Trim();
myprofile.Contact.Mobile = tbMobile.Text.Trim();
}
Upvotes: 0
Reputation: 430
all the transactions must be done before page unload. if page is unloaded then its all function calls will also be removed or stopped in midway.
Upvotes: 0