【问题标题】:ASP.NET Profile save overwritten by old valuesASP.NET 配置文件保存被旧值覆盖
【发布时间】:2011-09-07 13:22:03
【问题描述】:

我正在网站中使用ASP.NET 的个人资料功能。更新个人资料很奇怪!用户不能更新他/她自己的个人资料,无论是网站用户还是管理员,但管理员可以更新其他用户的个人资料。

在后端,调用 Profile 的 save() 后,SQL Server 跟踪显示 aspnet_Profile_SetProperties 存储过程被调用了两次。首先是新的价值观,然后是旧的价值观。第二次执行是在页面卸载后完成的。我的代码与交易无关。

为什么会这么奇怪?

aspnet_regsql的安装可能有问题,因为我已经卸载并再次安装它!?

代码

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>

背后的代码

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());
    }

【问题讨论】:

  • 请发布与配置文件相关的 web.config 部分。尝试获取第二次保存配置文件的堆栈跟踪!
  • 在调用堆栈窗口中,我可以看到母版页呈现控件,一旦完成,aspnet_Profile_SetProperties 程序就会被执行。找不到调用方来源。
  • 你能说明你在哪里以及如何调用 UpdateProfile() 吗?
  • @ibram: myprofile.Save()
  • @Reddy S R myprofile.Save() 被调用 FROM UpdateProfile() 你在哪里调用 UpdateProfile()

标签: c# asp.net sql-server-2005 asp.net-profiles


【解决方案1】:

默认情况下,配置文件会在 ASP.NET 页面执行结束时自动保存,请参阅profile Element (ASP.NET Settings Schema) 文档。这解释了您观察到的第二个“神秘”保存。

你可以尝试将automaticSaveEnabled改为false。

【讨论】:

  • 您的解决方案很有魅力!多谢了。只是想知道为什么自动保存会覆盖我的保存!在调用 Profile.save() 之后,我尝试将 endresponse 标志设置为 true 的重定向页面,但是它也不起作用。西蒙有什么想法吗?再次感谢!
  • 我有另一个应用程序没有发生这种覆盖!我看不到那个应用程序和这个应用程序之间的任何变化。
  • 您在答案中发布的链接不再存在。这样一来,这个答案的价值就会下降很多。
  • 感谢 Simon 更新链接。
  • 救命稻草。谢谢。
【解决方案2】:

您可能需要清除 web.config 中的默认提供程序。 像这样:

<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>

这是一个很好的解释: Removing existing profile providers

这是另一个不错的网站: http://odetocode.com/articles/440.aspx

【讨论】:

    【解决方案3】:

    应该通过 HttpContext.Current.Profile 访问 ProfileCommon,因为这是对当前用户配置文件(登录或匿名)的引用,您不需要显式调用 Save。试试这个:

    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();
    }
    

    【讨论】:

      【解决方案4】:

      所有事务必须在页面卸载之前完成。 如果页面被卸载,那么它的所有函数调用也将在中途被删除或停止。

      【讨论】:

      • 无法在此处调用任何代码寻址事务。此外,管理员能够更新其他用户的配置文件。在这种情况下,交易是如何通过的,而不是在更新自己的个人资料时?
      猜你喜欢
      • 1970-01-01
      • 2020-06-25
      • 1970-01-01
      • 2014-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-17
      • 1970-01-01
      相关资源
      最近更新 更多