سؤال

Problem. In a registration scenario, I'm trying to insert a user in my User table and then call WebSercurity.CreateAccount for that user (in a transaction). This causes the error that MS DTC is not available on the server.

Description. The reason I'm doing this is because I have a Customer Entity which inherits from User, so WebSercurity.CreateUserAndAccount cannot be used because it doesn't know about Customer and just inserts a User record.

I'm using Asp.net MVC 4 with EntityFramework 5, CodeFirst, and SQL Server 2008 R2.

any suggestions for not using DTC would be appreciated!

EDIT. It is obvious why this error occurs, because websecurity uses its own connection to the database, and my repositories use another connection, although I've configured simplemembership to use the same DbContext class as my repositories, but the problem is it creates a new instance of the DbContext ...

I was hoping if there is a way to pass an existing context object, or connection to the WebSecurity to use with its methods.

here's the code:

        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();
            //}
هل كانت مفيدة؟

المحلول 2

I found a possible solution but I'm not sure if it's the best solution. The idea came from this blog post that says how we can include simplemembership tables in our POCO entities and create the tables ourselves (not using WebSecurity).

So as a result I think I can implement the CreateAccount method in my repositories by simply inserting a record in the webpages_Membership table, and AddUserToRole by inserting a record in webpages_UsersInRoles table. For other queries like GetUser and ... we can use WebSecurity and Roles class like before.

It seems to work OK (otherwise I'm missing something), but has some extra work to do which I wish not to!

So if anyone can give me a better solution I would be glad.

نصائح أخرى

The DTC error occurs because you are trying to span a transaction over two different database connections. You have several options.

SimpleMembership is designed for simple scenarios. You are doing an advanced scenario, so you should probably use a different membership provider.

As Mystere Man pointed out the error is occurring because the transaction is over two different databases. You have several options. Here are a few that come to mind.

You can customize the existing User entity used by the SimpleMembership provider to capture the custom information you want for each user. This is fairly straightforward and is discussed in this blog post. It looks like you are trying to do an email confirmation which the SimpleMembership provider also supports and is discussed here.

You can also tie the information in your other database with the unique user ID (int) that SimpleMembership uses. Once you create the user and log them in you can get that id by calling WebSecurity.CurrentUserId.

You could bypass the whole SimpleMempership provider and create your own custom membership provider, which is discussed here.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top