【问题标题】:Migrating Anonymous Users in MVC5 with Identity 2.x使用 Identity 2.x 在 MVC5 中迁移匿名用户
【发布时间】:2015-06-02 10:54:58
【问题描述】:

我的问题与这个问题密切相关(但是,除非您阅读了那里的所有 cmets 和答案,否则您可能无法弄清楚):

Does ASP.NET Identity 2 support anonymous users?

我只是想详细说明或问得更清楚一点。我的问题也与这篇关于迁移匿名用户的 Microsoft 文章有关:

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 => 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 可能已经让匿名用户考虑得更彻底一些?实际上,Identity 似乎根本没有考虑匿名用户。

【问题讨论】:

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


    【解决方案1】:

    嗯...这是我能做的最好的事情,不知道还有多少天。我不会将其标记为已接受的答案,因为我真的不觉得它是。为了在我死前的某个时候完成这个项目(因为 .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 最多只能有一个重复记录,因此它似乎是宜居的。不过,我很想知道一个更好的方法。

    希望这可以帮助像我这样的可怜失落的灵魂。我很想听听任何其他批评、陷阱、建议等。谢谢。

    【讨论】:

      猜你喜欢
      • 2018-01-11
      • 2014-06-05
      • 1970-01-01
      • 2021-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-01
      • 1970-01-01
      相关资源
      最近更新 更多