none
user.identity.name 和 membership.getuser().name 的区别 RRS feed

  • 问题

  • 最近使用 asp.net 碰到一个非常非常奇怪的问题:
    我在页面上有一个 LoginName 控件,一个LoginStatus控件,还有一个Label 控件。
    众所周知:LoginName 控件,可以显示当前的登录用户名;LoginStatus可以显示当前的登录状态;
    而我的Label控件用来显示登录用户的中文名(这些信息存在于数据库中)

    然后,我用 Membership.GetUser().UserName 作为参数,来从数据库进行查询,获取到其中文名后,在Label中显示;

    正常情况下:
    不登录时,LoginStatus 显示“登录”,LoginName 不显示;如果用户已登录,则LoginStatus显示“注销”;LoginName 显示登录的用户名,而Label显示中文名;
    不正常时情况下:
    LoginStatus 显示“注销”,而Label显示“未登录”(这个内容是我自己定义的)-------这时我不知道用户是登录了还是没有登录;

    非常非常疑惑的问题:
    从网上查到,LoginName 是用User.Identity.Name来显示的,那么问题就来了:Membership.Getuser().UserName 与 User.Identity.Name 有什么区别,又有什么联系?
    为什么一个显示为登录(User.Identity.Name),而另一个却显示为未登录(Membership.Getuser().UserName,这时MemberShip.GetUser()为null)?
    2009年12月31日 21:53

答案

全部回复

  • 惊奇的发现,这是2010年的第一帖,而我的这个回复可能也是第一个回复了吧
    2009年12月31日 21:58
  • User.Identity.Name是读取cookie验证的用户字符串
    Membership.Getuser().UserName是读取asp.net内置数据库里的用户字符串  注意这个方法只能在windows模式验证用户才能用的 表单模式不能用
    2010年1月1日 5:29
  • 这种说法好象不对,表单模式当然可以用,为什么不能用呢?
    2010年1月1日 6:10
  • 这种说法好象不对,表单模式当然可以用,为什么不能用呢?
    确实不对的 抱歉
    除非你没有通过验证 你看看web.config模式是否正确 
    方法内置  
    http://www.taoshibao.com/TSBNews/ReadNewsMsg.aspx?ArticleCode=20091225081308328 参考
    • 已编辑 mldark 2010年1月1日 6:45
    2010年1月1日 6:17
  • 区别是 如果你的数据库没有存在登陆的用户字符串的值 返回null 因为读取cookie后再检查数据库有没有相关的值才能返回的值
    2010年1月1日 6:37
  • http://www.taoshibao.com/TSBNews/ReadNewsMsg.aspx?ArticleCode=20091225081308328 参考
    从这篇文章可以看出,如果用户登录,并且在数据库中有该用户,并且该用户在线,那么就可以返回这个用户的membershipuser;
    但从我上面的问题,LoginName 是有用户名的,如果 Membership.GetUser 没有返回正确的用户,那只有一种可能,就是该用户不在线了。
    既然该用户不在线了,为什么 LoginName 是有用户名的?因为它与Membership 没有关系。而Membership.GetUser() 是基于 User.Identity.UserName 的。
    这也就是说:
    用户的Session还没有过期(比如20分钟),但超过了Membership 的在线检测时间(比如:10分钟),这样就导致了Membership.GetUser()无法获取到用户。从而出现了这个错误?

    如果真是这样的话,MemberShip 的检测在线时间与站点的Session过期时间有何关联?如何使它们保持一致?

    多谢 mldark ,还请给予提示。
    2010年1月1日 17:22
  • System.Web.Security.Membership.UserIsOnlineTimeWindow 这个属性就是检测时间
    在web.config配置这个属性即可
    http://ugoer.cnblogs.com/archive/2005/09/17/238978.html

    2010年1月2日 4:28
  • 我想此问题可能归结为以下三个超时状态的设置:
    1、站点的会话超时
    2、身份验证的COOKIE超时;
    3、Membership 的用户在线状态设置,即UserIsOnLineTimeWindow

    默认的:
    会话超时是20分钟;
    身份验证的Cookie超时是30分钟;
    Membership 的用户在线状态超时默认为15分钟

    这三者之间应如何设置才是合理的?

    我现在的问题是:当仍然可以获得用户的登录帐号时,却无法通过此帐号获得用户的附加信息(自定义的,在数据库中),因为Membership.GetUser() 为空。
    2010年1月2日 8:35
  • 设置同样的值比较更佳的
    我怀疑你用登陆方式是否有问题的 说了那么多理论都是空想猜测 没有代码
    我测试了多种方式都是正常的

    2010年1月2日 9:44
  • 多谢mldark,下面的这段代码是在MasterPage中的:
            try
            {
                MembershipUser mu = Membership.GetUser();

                if (mu != null)
                {
                    UserInfo u = new UserInfo(mu.UserName, sconn);
                    //UserInfo u = new UserInfo(Page.User.Identity.Name, sconn);
                    ((Label)LoginView1.FindControl("lblName")).Text = u.JawName + "," + u.UserName;//在Label 控件上显示用户的单位和名字
                }
                else
                {
                    ((Label)LoginView1.FindControl("lblName")).Text = "您已不在线,请重新登录";//这个其实是不必要的,但因为出现了我在一开始提出的那个问题,所以才加上这个作为测试;即:这里显示 的是不在线,而LoginName显示了用户的登录名,LoginStatus控件显示了注销(即还在登录状态)
                }

            }
            catch (Exception)
            { }

    代码很简单,不知道有没有问题。
    出现前述的问题时,所有的超时设置都是默认值。

    2010年1月2日 21:46
  • 除非你没有通过验证 你看看web.config模式是否正确 
    方法内置  
    http://www.taoshibao.com/TSBNews/ReadNewsMsg.aspx?ArticleCode=20091225081308328 参考

    为方便讨论,我将你给的这段代码也粘过来看
    //Membership 类内部
        public static MembershipUser GetUser()
        {
            return GetUser(GetCurrentUserName(), true);
        }

        //Membership 类内部私有函数
        private static string GetCurrentUserName()
        {
            if (HostingEnvironment.IsHosted)
            {
                HttpContext current = HttpContext.Current;
                if (current != null)
                {
                    return current.User.Identity.Name;
                }
            }
            IPrincipal currentPrincipal = Thread.CurrentPrincipal;
            if ((currentPrincipal != null) && (currentPrincipal.Identity != null))
            {
                return currentPrincipal.Identity.Name;
            }
            return string.Empty;
        }

        //Membership 类内部函数
        public static MembershipUser GetUser(string username, bool userIsOnline)
        {
            SecUtility.CheckParameter(ref username, true, false, true, 0, "username");
            return Provider.GetUser(username, userIsOnline);
        }

    2010年1月2日 22:00
  • 当我将站点会话超时设为默认的20
    Cookie超时设为5
    UserIsOnlineTimeWindow 设为2时,好象没有出现过这种问题
    2010年1月2日 22:03
  • 你干脆制定一个参数看看
    MembershipUser mu = Membership.GetUser(Page.User.Identity.Name);
    2010年1月3日 5:09

  • 其实我觉得mldark最开始的回答已经说出了原因。


    User.Identity.Name是读取cookie验证的用户字符串
    Membership.Getuser().UserName是读取asp.net内置数据库里的用户字符串

    Microsoft Online Community Support
    2010年1月4日 7:26
  • 上楼版主的说法是对的,不过我的问题不并在从哪里读取,而是出问题时:
    User.Identity.Name可以获得;
    而Membership.Getuser()无法获得登录用户,自然获得不了Name;其实Membership.Getuser()也是通过User.Identity.Name作为参数获得的。

    2010年1月5日 8:11
  • 上楼版主的说法是对的,不过我的问题不并在从哪里读取,而是出问题时:
    User.Identity.Name可以获得;
    而Membership.Getuser()无法获得登录用户,自然获得不了Name;其实Membership.Getuser()也是通过User.Identity.Name作为参数获得的。


    这个问题可能有几个原因
    第一 未连接数据库 造成没有查询出来
    第二cookie过时期 造成查询不出
    2010年1月5日 8:35
  • 还有个情况未说明:
    我的开发数据库和生产数据库是一个库,会不会由于之间的切换造成这一问题呢?
    2010年1月5日 9:06
  • 还有个情况未说明:
    我的开发数据库和生产数据库是一个库,会不会由于之间的切换造成这一问题呢?

    一般情况不会  发来你的web.config配置看看
    2010年1月5日 9:47
  • <?xml version="1.0"?>
    <!--
        注意: 除了手动编辑此文件以外,您还可以使用
        Web 管理工具来配置应用程序的设置。可以使用 Visual Studio 中的
         “网站”->“Asp.Net 配置”选项。
        设置和注释的完整列表在
        machine.config.comments 中,该文件通常位于
        \Windows\Microsoft.Net\Framework\v2.x\Config 中
    -->
    <configuration>
     <configSections>
      <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
       <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
        <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
        <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
         <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
         <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
         <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
         <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
        </sectionGroup>
       </sectionGroup>
      </sectionGroup>
     </configSections>
     <appSettings/>
     <connectionStrings>
      <remove name="LocalSqlServer" />
      <add name="PrjConn" connectionString="Data Source=127.0.0.1;Initial Catalog=jawczj;Persist Security Info=True;User ID=****;Password=****"
       providerName="System.Data.SqlClient" />
       </connectionStrings>
     <system.web>
      <!--
                设置 compilation debug="true" 可将调试符号插入
                已编译的页面中。但由于这会
                影响性能,因此只在开发过程中将此值
                设置为 true。
            -->
      <sessionState timeout="5" />
      <membership userIsOnlineTimeWindow="2">
       <providers>
        <remove name="AspNetSqlMembershipProvider" />
        <add connectionStringName="prjconn" enablePasswordRetrieval="false"
         enablePasswordReset="true" requiresQuestionAndAnswer="false"
         applicationName="/" requiresUniqueEmail="false" passwordFormat="Clear"
         maxInvalidPasswordAttempts="20" minRequiredPasswordLength="7"
         minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
         passwordStrengthRegularExpression="" name="AspNetSqlMembershipProvider"
         type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
       </providers>
      </membership>
      <roleManager enabled="true">
       <providers>
        <remove name="AspNetSqlRoleProvider"/>
        <add connectionStringName="prjconn" applicationName="/" name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
       </providers>
      </roleManager>
      <compilation defaultLanguage="c#" debug="true">
       <assemblies>
        <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
        <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
        <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
        <add assembly="System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/></assemblies>
      </compilation>
      <!--
                通过 <authentication> 节可以配置 ASP.NET 用来
                识别进入用户的
                安全身份验证模式。
            -->
      <authentication mode="Forms">
       <forms timeout="5" />
      </authentication>
      <!--
                如果在执行请求的过程中出现未处理的错误,
                则通过 <customErrors> 节可以配置相应的处理步骤。具体说来,
                开发人员通过该节可以配置
                要显示的 html 错误页
                以代替错误堆栈跟踪。

            <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
                <error statusCode="403" redirect="NoAccess.htm" />
                <error statusCode="404" redirect="FileNotFound.htm" />
            </customErrors>
            -->
      <pages theme="default">
       <controls>
        <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
       </controls>
      </pages>
      <httpHandlers>
       <remove verb="*" path="*.asmx"/>
       <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
       <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
       <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
      </httpHandlers>
      <httpModules>
       <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      </httpModules>
     </system.web>
     <system.codedom>
      <compilers>
       <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <providerOption name="CompilerVersion" value="v3.5"/>
        <providerOption name="WarnAsError" value="false"/>
       </compiler>
       <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" warningLevel="4" type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <providerOption name="CompilerVersion" value="v3.5"/>
        <providerOption name="OptionInfer" value="true"/>
        <providerOption name="WarnAsError" value="false"/>
       </compiler>
      </compilers>
     </system.codedom>
     <!--
            在 Internet 信息服务 7.0 下运行 ASP.NET AJAX 需要 system.webServer
            节。对早期版本的 IIS 来说则不需要此节。
        -->
     <system.webServer>
      <validation validateIntegratedModeConfiguration="false"/>
      <modules>
       <remove name="ScriptModule"/>
       <add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      </modules>
      <handlers>
       <remove name="WebServiceHandlerFactory-Integrated"/>
       <remove name="ScriptHandlerFactory"/>
       <remove name="ScriptHandlerFactoryAppServices"/>
       <remove name="ScriptResource"/>
       <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
       <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
       <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      </handlers>
     </system.webServer>
     <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <dependentAssembly>
        <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
       </dependentAssembly>
       <dependentAssembly>
        <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
       </dependentAssembly>
      </assemblyBinding>
     </runtime>
    </configuration>

    2010年1月6日 21:06
  • 貌似没问题 你干脆重新创建新的项目 只有内置数据库 再测试看看 原因不好找
    2010年1月7日 7:42