5

Problema. In uno scenario di registrazione, sto cercando di inserire un utente nella mia tabella Utente e quindi di chiamare WebSercurity.CreateAccount per quell'utente (in una transazione). Ciò causa l'errore che MS DTC non è disponibile sul server.utilizzando WebSercurity.CreateAccount con altre query in un TrasactionScope, senza DTC abilitato

Descrizione. Il motivo per cui sto facendo questo è perché ho un'entitàche eredita da User, quindi non è possibile utilizzare WebSercurity.CreateUserAndAccount perché non sa di Customer e inserisce semplicemente un record User.

Sto utilizzando Asp.net MVC 4 con EntityFramework 5, CodeFirst e SQL Server 2008 R2.

sarebbe apprezzato qualsiasi suggerimento per non usare DTC!

MODIFICA. È ovvio perché si verifica questo errore, perché websecurity utilizza la propria connessione al database e i miei repository utilizzano un'altra connessione, sebbene io abbia configurato la funzione simplemembership per utilizzare la stessa classe DbContext come repository, ma il problema è che crea un nuova istanza di DbContext ...

Speravo se ci fosse un modo per passare un oggetto contesto esistente, o una connessione allo WebSecurity da usare con i suoi metodi.

Ecco il codice:

 if (ModelState.IsValid) 
     { 
      //using (TransactionScope tx = new TransactionScope()) 
      //{ 
       UnitOfWork.UserRepository.Insert(new Customer 
       { 
        FirstName = model.FirstName, 
        LastName = model.LastName, 
        Email = model.Email, 
        Tel = model.Tel, 
        Mobile = model.Mobile, 
        BirthDate = model.BirthDate, 
        InsertDate = DateTime.Now, 
        UserType = UserType.Customer, 
        MaritalStatus = model.MaritalStatus, 
        ZipCode = model.ZipCode, 
        StreetAddress = model.StreetAddress, 
        City = model.City, 
        State = model.State 
       }); 
       UnitOfWork.Commit(); 

       string token = WebSecurity.CreateAccount(model.Email, model.Password, true); 

       Roles.AddUserToRole(model.Email, "Customer"); 
       //WebSecurity.Login(model.Email, model.Password, true); 

       await Task.Run(() => EmailHelper.SendConfrimationEmail(token, model.Email)); 

      // tx.Complete(); 
      //} 

risposta

1

Ho trovato una soluzione possibile ma non sono sicuro che sia la soluzione migliore. L'idea è venuta da questo blog post che dice come possiamo includere le tabelle simplemembership nelle nostre entità POCO e creare noi stessi le tabelle (non usando WebSecurity).

Così come risultato credo di poter implementare il metodo CreateAccount nei miei archivi, semplicemente inserendo un record nella tabella webpages_Membership, e AddUserToRole inserendo un record in webpages_UsersInRoles tavolo. Per altre domande come GetUser e ... possiamo usare la classe WebSecurity e Roles come prima.

Sembra funzionare bene (altrimenti mi manca qualcosa), ma ha del lavoro extra da fare che non desidero!

Quindi se qualcuno mi può dare una soluzione migliore sarei felice.

1

L'errore DTC si verifica perché si sta tentando di abbracciare una transazione su due diverse connessioni al database. Hai diverse opzioni.

SimpleMembership è progettato per scenari semplici. Stai facendo uno scenario avanzato, quindi dovresti probabilmente usare un altro provider di appartenenza.

+0

Grazie, sì, lo so, non c'è un modo per passare la connessione ai metodi 'WebSecurity'? quali fornitori di abbonamento suggerisci? – Ashkan

0

Come Mystere Man ha rilevato che si è verificato un errore perché la transazione è su due diversi database. Hai diverse opzioni. Ecco alcuni che vengono in mente.

È possibile personalizzare l'entità utente esistente utilizzata dal provider SimpleMembership per acquisire le informazioni personalizzate desiderate per ciascun utente. Questo è abbastanza semplice ed è discussed in this blog post.Sembra che tu stia provando a fare una conferma via e-mail che il provider SimpleMembership supporta ed è discussed here.

È inoltre possibile associare le informazioni nell'altro database con l'ID utente univoco (int) utilizzato da SimpleMembership. Dopo aver creato l'utente e aver effettuato l'accesso, è possibile ottenere tale ID chiamando WebSecurity.CurrentUserId.

È possibile ignorare l'intero provider SimpleMempership e creare il proprio provider di appartenenza personalizzato, ovvero discussed here.

+0

Grazie per la risposta. circa ** opzione 1 **: sto esattamente usando questo approccio. la mia entità 'Utente' ha informazioni personalizzate di cui ho bisogno, il mio problema è che ho 2 tipi di Utente: Cliente e Agente che ereditano Utente! about ** option 2 **: Sto facendo anche questo! Il mio problema è qualcos'altro (o non ho capito il tuo punto!). ma il link aveva alcune informazioni utili. Grazie. e circa ** opzione 3 **: non voglio reinventare la ruota. – Ashkan

Problemi correlati