使用Identity 2.x迁移MVC5中的匿名用户

时间:2015-06-02 10:54:58

标签: c# asp.net .net asp.net-mvc asp.net-identity

我的问题与这个问题密切相关(但是,除非你阅读那里的所有评论和答案,否则你可能无法解决这个问题):

Does ASP.NET Identity 2 support anonymous users?

我只是想详细说明或者问清楚一点。我的问题也是关于这篇关于迁移匿名用户的微软文章:

https://msdn.microsoft.com/en-us/library/system.web.profile.profilemodule.migrateanonymous(v=vs.110).aspx

我想最简单的问题是,MSDN文章是否仍然是当前/相关的,用于迁移MVC5 Identity 2.X中的匿名用户?首先,它提到了这一点:

<authentication mode="Forms" >
  <forms loginUrl="login.aspx" name=".ASPXFORMSAUTH" />
</authentication>

然而,在我的web.config中,我有这个(由我以外的东西添加......我假设身份或项目模板。):

<system.webServer>
<modules>
  <remove name="FormsAuthentication" />
</modules>

我也在我的web.config中使用它,它似乎适用于处理匿名用户(它是我添加的,并在MSDN文章中提到):

<anonymousIdentification enabled="true" />

有两种方式可以从匿名转到IsAuthenticated,无论是注册还是登录。

基本上,无论匿名用户被允许做什么,我都会抓取AnonymousID并将其放入带有相关信息的单独表格中(例如CommentId =&gt; AnonymousId)。 (理论上,用户可能已经注册并注销并仍然充当匿名用户......实质上是复制操作,当用户登录时再次迁移数据时需要考虑这些操作,因此它不会创建重复项。)

我引用的这两个链接以及其他几篇文章都涉及到这个主题,但没有什么是真正清楚或很好解释的。关于第一块代码,是否有新的authentication mode?假设我们还没有使用Forms,我错了吗? MSDN示例是否仍然是最新的?什么是更好的示例(如果可能)或更多当前的方式将匿名用户迁移到IsAuthenticated以及匿名用户可能链接到的任何其他表数据?

谢谢。

更新1(第二天):以下是我到目前为止所拥有的内容: Global.asax中的Profile_OnMigrateAnonymous仍会在成功注册和登录事件时触发。评论在示例中添加:

public void Profile_OnMigrateAnonymous(object sender, ProfileMigrateEventArgs args)
    {
        //Anything regarding this profile stuff appears to not be relevant to Identity...
        //... (and no using statements I can find will get rid of the squigglies...
        //... Even if I get rid of the Profile error, GetProfile has problems.)
        //ProfileCommon anonymousProfile = Profile.GetProfile(args.AnonymousID);

        //More Profile stuff and not even relevant to what I'm doing...
        //...and appears to be new fields you can add to the SimpleMembership Users table?
        //...and also related to the properties you add in your web.config which are also...
        //...not related to Identity.
        //Profile.ZipCode = anonymousProfile.ZipCode;
        //Profile.CityAndState = anonymousProfile.CityAndState;
        //Profile.StockSymbols = anonymousProfile.StockSymbols;

        ////////
        //// Delete the anonymous profile. If the anonymous ID is not 
        //// needed in the rest of the site, remove the anonymous cookie.
        //The ProfileManager line just hangs and barks about a network error...
        //...but there is no network error (without a doubt)...
        //...I have no idea what it would be deleting anyway.
        //ProfileManager.DeleteProfile(args.AnonymousID);
        //This is the only line that is successful and actually deletes the cookie.
        AnonymousIdentificationModule.ClearAnonymousIdentifier();

        //// Delete the user row that was created for the anonymous user.
        // Except that no user was written to any user rows...
        // ...Therefore, I didn't even bother trying this next line.
        //Membership.DeleteUser(args.AnonymousID, true);

    }

正如您所看到的,只有一行似乎在带有Identity的msdn示例中起作用(...而且一般来说,cookie似乎也与Identity无关。)事实上,我只是得到了Profile_OnMigrateAnonymous的一些搜索结果以及与此相关的其他项目,包括国际结果,让我觉得这不是一种流行的做事方式吗?似乎SimpleMembership可能让匿名用户想得更彻底一点?实际上,匿名用户根本没有想到身份。

1 个答案:

答案 0 :(得分:0)

嗯......这是我能做的最好的事情而不会杀死谁知道多少天。我不会将其标记为已接受的答案,因为我并不觉得它是真的。希望在我死前的某个时间完成这个项目(因为.NET每天老化〜1年),我只需要采用尼安德特人的方法并逐步完成这对我来说是否合理。

我做的第一件事是在我的桌子上创建一个唯一的约束(在同一个sql表中没有相同的两个数据的副本,即IncidentId和IUserId):

    CREATE UNIQUE NONCLUSTERED INDEX idx_incidentid_iuserid
    ON Likes(IncidentId, IUserId)

在我的global.asax中(那里还没有):

    ...
    using System.Web.Security;
    using Microsoft.AspNet.Identity;
    using ProjectSender.Models;
    ...
    ...
        public void Profile_OnMigrateAnonymous(object sender, ProfileMigrateEventArgs args)
        {
            ApplicationDbContext db = new ApplicationDbContext();
            var anonymousUser = args.AnonymousID;
            var identityUser = User.Identity.Name;
            var identityUserId = User.Identity.GetUserId();

            foreach (var item in db.Likes.Where(x => x.IUserId == anonymousUser).ToList())
            {
                //Try = Update anonymousId with identityUserId. 
                //Catch = Remove any duplicates caught by the exception/constraint
                try
                {
                    item.IUserId = identityUserId;
                    item.IUser = identityUser;
                    db.SaveChanges();
                }
                catch
                {
                    db.Likes.Remove(item);
                    db.SaveChanges();
                }
            }

            // Remove the anonymous cookie.
            AnonymousIdentificationModule.ClearAnonymousIdentifier();
        }
    ...

我认为为这个约束抛出一个异常可能不是表现最好的事情,但我只是不知道其他任何方式来执行它。对于该用户,每个IncidentId最多只能有一个重复记录,因此它似乎是宜居的。但是,我想知道更好的方法。

希望这能帮助一些像我一样的穷人失去灵魂。我很想听到任何其他批评,陷阱,建议等等。谢谢。