2016-07-07 17 views
3

gefunden Wenn ich einen Benutzer mit dem folgenden Code registrieren:MVC - InvalidOperationException: UserId nicht

// POST: /Account/Register 
[HttpPost] 
[AllowAnonymous] 
[ValidateAntiForgeryToken] 
public async Task<ActionResult> Register(RegisterViewModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     var user = new ApplicationUser() { UserName = model.UserName }; 

     IdentityResult result = await UserManager.CreateAsync(user, model.Password); 

     if (result.Succeeded) 
     { 
      await SignInAsync(user, isPersistent: false); 
      return RedirectToAction("Index", "Home"); 
     } 
     else 
     { 
      AddErrors(result); 
     } 

     return View(model); 
    } 
} 

Ich bin in der Lage alle Ansichten mit dem [autorisieren] Attribut zuzugreifen. Allerdings, wenn ich abmelden und mit dem gleichen Benutzer ich mit

eine Fehlerseite zurückkommen in „InvalidOperationException: UserId nicht gefunden“

Der Fehler scheint aus meiner SignInAsync Funktion zu kommen an die Aussage:

var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); 

ich füge keine Benutzer-ID und es gibt in dem Benutzer classs (seine Id) oder in der AspNetUsers Tabelle kein Benutzer-ID-Feld. Der Benutzer existiert in dieser Tabelle, aber es gibt auch keine UserId.

Ich habe versucht, die Cookies usw. zu löschen, aber immer noch kein Glück bei der Neuanmeldung. Mache ich das Register falsch? Ich verstehe nicht, warum die Authentifizierung nach dem UserId-Feld sucht, wenn es nicht zu existieren scheint

EDIT: Wenn ich beim ersten Mal anmelden ... bekomme ich die Fehlerseite. Wenn ich die Seite aber wieder öffne und den Cookie lese, habe ich Zugriff auf alles. Was zum Teufel geht mit dem ersten Login?

hier ist die SignInAsync Methode:

private async Task SignInAsync(ApplicationUser user, bool isPersistent) 
     { 
      AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie); 
      var _identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); 

      AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, _identity); 
     } 

Aufnahme:

public class ApplicationUser : IdentityUser 
    { 
     public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) 
     { 
      // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType 
      var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); 
      // Add custom user claims here 
      return userIdentity; 
     } 
    } 
+0

Können Sie Ihr Benutzermodell teilen? – Neshta

+0

der Benutzer ist eine IPristinal-Implementierung. Ich denke, dass es gebacken ist. und das Benutzerobjekt ist ein IdentityUser – rigamonk

+0

Könnten Sie uns die Implementierung der Methode SignInAsync (user, isPersistent: false) zeigen? –

Antwort

0

Edit: Ich bin falsch über Sie Dapper erwähnt zu haben, so dass die Dapper-spezifische Details sind nicht relevant, aber Die allgemeine Idee der Fehlerbehebung bleibt bestehen - Ihre Id- und UserId-Spalten werden wahrscheinlich nicht richtig zugeordnet.


Ich lief gestern genau in diesen Fehler. Ich denke, Sie hatten zuvor erwähnt, dass Sie Dapper als Datenzugriffsmechanismus verwenden. Ich denke, das war vielleicht relevant, weil Sie auch erwähnt haben, dass die Tabelle ein Feld Userid hat, aber Ihre Benutzerklasse eine Eigenschaft Id hat. Ich vermute, Sie können auch einen Code haben, um der Id Eigenschaft einen neuen Guid zuzuweisen, wenn dort keiner ist. Etwas wie folgt aus:

public ApplicationUser() 
{ 
    Id = Guid.NewGuid().ToString(); 
} 

Dies in Kombination mit wie Dapper Mapping Arbeiten können Sie am seit dem Id Feld werden Messing wird mit dem neuen Guid statt der aufzuwickeln es soll aus der Tabelle zu lesen.

Im folgenden Beispiel kann Dapper das ID-Feld ApplicationUser nicht zuweisen, da das DB-Feld anders als die Eigenschaft der Klasse benannt ist. Aber es hat bereits einen Id-Wert von seinem Konstruktor. Dies führt dazu, dass spätere Aufrufe an FindByIdAsync() und Freunde fehlschlagen.

public async Task<ApplicationUser> FindByNameAsync(string userName) 
{ 
    ApplicationUser result = null; 

    using (var conn = await GetOpenDBConnection()) 
    { 
     try 
     { 
      // this query is bugged with Dapper because UserId does not 
      // exist on ApplicationUser. 
      var queryResults = await conn.QueryAsync<ApplicationUser>(
       "SELECT UserId, UserName, Email FROM dbo.Users WHERE UserName = @UserName;", 
       new { UserName = userName }); 

      result = queryResults.FirstOrDefault(); 
     } 
     catch (Exception ex) 
     { 
          //handle error appropriately. 
      result = null; 
     } 
    } 

    return result; 
} 

Wenn es in der Tat ein Dapper Zuordnungsproblem ist, können Sie entweder das Feld in den Abfrageergebnissen umbenennen wie SELECT UserId as [Id], UserName, Email FROM dbo.Users WHERE UserName = @UserName oder sehen Randall Stutton's answer, wie Dapper Felder in einer wirklich saubere Art und Weise abzubilden.

Verwandte Themen