title: SqlMembershipProvider Membership.GetUser by name failing
body: <p><strong>The problem</strong>
  Membership.GetUser works fine if I use the GUID, but fails if I try it without parameters or with the name:</p>
  
  <pre><code>//This works and adds records to aspnet_user &amp; aspnet_Membership tables
  MembershipUser membershipUser = Membership.CreateUser(_name, _pwd, _email, null, null, true, null, out createStatus); 
  
  //These fail with an InvalidCastException
  MembershipUser membershipUser2 = Membership.GetUser(_name, true);
  MembershipUser membershipUser3 = Membership.GetUser();
  
  //If I go look up the GUID for this user (userId), this works!
  MembershipUser membershipUser4 = Membership.GetUser(new Guid("E1428CD3-CF17-494E-AB77-CF8F6010F585"), true);
  </code></pre>
  
  <p><strong>Other Mysteries</strong></p>
  
  <pre><code>//This works
  Int32 count = Membership.GetNumberOfUsersOnline();    
  
  //this fails (but totalRecords has the right value)
  Int32 totalRecords;
  MembershipUserCollection col = Membership.GetAllUsers(0,100, out totalRecords);
  </code></pre>
  
  <p><strong>The Setup</strong></p>
  
  <ul>
  <li>MVC</li>
  <li>.NET 4.0</li>
  <li>Default SQL Membership Provider (no custom or overrides)</li>
  </ul>
  
  <p>ex:</p>
  
  <pre><code>&lt;membership defaultProvider="SqlProvider"&gt;
      &lt;providers&gt;
        &lt;clear /&gt;
        &lt;add name="SqlProvider" 
             type="System.Web.Security.SqlMembershipProvider" 
             connectionStringName="MyDB" 
             enablePasswordRetrieval="false" 
             enablePasswordReset="true" 
             requiresQuestionAndAnswer="false" 
             applicationName="myapp" 
             requiresUniqueEmail="false" 
             passwordFormat="Hashed" 
             maxInvalidPasswordAttempts="5" 
             minRequiredPasswordLength="2" 
             minRequiredNonalphanumericCharacters="0" 
             passwordAttemptWindow="10"
             passwordStrengthRegularExpression="" /&gt;
      &lt;/providers&gt;
  &lt;/membership&gt;
  </code></pre>
  
  <ul>
  <li>Standard aspnet_* database tables with no customization or extra keys</li>
  <li>aspnet_Membership_GetAllUsers runs fine manually from the DB.  Redirected output shows the expected results are being returned</li>
  <li>aspnet_Membership_GetUserByName is working as well from the DB</li>
  </ul>
  
  <p><strong>Exception Details</strong></p>
  
  <pre><code>Specified cast is not valid.
     at System.Data.SqlClient.SqlBuffer.get_SqlGuid()
     at System.Data.SqlClient.SqlDataReader.GetGuid(Int32 i)
     at System.Web.Security.SqlMembershipProvider.GetUser(String username, Boolean userIsOnline)
     at System.Web.Security.Membership.GetUser(String username, Boolean userIsOnline)
  </code></pre>
  
  <p><strong>Thoughts</strong></p>
  
  <p>It's almost like there's something wrong inside the Membership.GetUser method.  I reflected out the code for the System.Web.Security.SqlMembershipProvider.GetUser for my System.Web.dll (version 4.0) and I get the following:</p>
  
  <pre><code>public override MembershipUser GetUser(string username, bool userIsOnline)
  {
    SecUtility.CheckParameter(ref username, true, false, true, 256, "username");
    SqlDataReader reader = (SqlDataReader) null;
    try
    {
      SqlConnectionHolder connectionHolder = (SqlConnectionHolder) null;
      try
      {
        connectionHolder = SqlConnectionHelper.GetConnection(this._sqlConnectionString, true);
        this.CheckSchemaVersion(connectionHolder.Connection);
        SqlCommand sqlCommand = new SqlCommand("dbo.aspnet_Membership_GetUserByName", connectionHolder.Connection);
        sqlCommand.CommandTimeout = this.CommandTimeout;
        sqlCommand.CommandType = CommandType.StoredProcedure;
        sqlCommand.Parameters.Add(this.CreateInputParam("@ApplicationName", SqlDbType.NVarChar, (object) this.ApplicationName));
        sqlCommand.Parameters.Add(this.CreateInputParam("@UserName", SqlDbType.NVarChar, (object) username));
        sqlCommand.Parameters.Add(this.CreateInputParam("@UpdateLastActivity", SqlDbType.Bit, (object) (bool) (userIsOnline ? 1 : 0)));
        sqlCommand.Parameters.Add(this.CreateInputParam("@CurrentTimeUtc", SqlDbType.DateTime, (object) DateTime.UtcNow));
        SqlParameter sqlParameter = new SqlParameter("@ReturnValue", SqlDbType.Int);
        sqlParameter.Direction = ParameterDirection.ReturnValue;
        sqlCommand.Parameters.Add(sqlParameter);
        reader = sqlCommand.ExecuteReader();
        if (!reader.Read())
          return (MembershipUser) null;
        string nullableString1 = this.GetNullableString(reader, 0);
        string nullableString2 = this.GetNullableString(reader, 1);
        string nullableString3 = this.GetNullableString(reader, 2);
        bool boolean1 = reader.GetBoolean(3);
        DateTime creationDate = reader.GetDateTime(4).ToLocalTime();
        DateTime lastLoginDate = reader.GetDateTime(5).ToLocalTime();
        DateTime lastActivityDate = reader.GetDateTime(6).ToLocalTime();
        DateTime lastPasswordChangedDate = reader.GetDateTime(7).ToLocalTime();
        Guid guid = reader.GetGuid(8);
        bool boolean2 = reader.GetBoolean(9);
        DateTime lastLockoutDate = reader.GetDateTime(10).ToLocalTime();
        return new MembershipUser(this.Name, username, (object) guid, nullableString1, nullableString2, nullableString3, boolean1, boolean2, creationDate, lastLoginDate, lastActivityDate, lastPasswordChangedDate, lastLockoutDate);
      }
      finally
      {
        if (reader != null)
          reader.Close();
        if (connectionHolder != null)
          connectionHolder.Close();
      }
    }
    catch
    {
      throw;
    }
  }
  </code></pre>
  
  <p><strong>Next Step</strong></p>
  
  <p>I'm hoping to get some direction from the SO crowd on where I should go next.  I figure I could either override this method and put together my own provider just to debug it, or I could just go around the darned thing and call out to the DB myself directly.  This seems like a lot of heartache from some basic DB CRUD.</p>
  
  <p><strong>Current Status</strong></p>
  
  <ul>
  <li>3/5/2013: I discovered this morning that my <code>aspnet_Users</code> table has the <code>UserId</code> as an <code>nvarchar(256)</code> instead of a <code>uniqueidentifier</code>.  Perhaps the <code>SqlDataReader.GetGuid()</code> is choking there.  I'll run some tests this evening to see if that's the problem.  I'm wondering if my table structure is outdated, because online documentation shows this field as a <code>uniqueidentifier</code>.  </li>
  </ul>