简体   繁体   English

在 .Net 核心和 .Net 标准身份框架之间共享通用数据库

[英]Sharing common database between .Net core and .Net standard Identity framework

I have old legacy MVC app that uses Identity 2.0 .我有使用Identity 2.0的旧版 MVC 应用程序。 Also recently I have created .Net 6 API with Identity 6.0 (AspNetCore.Identity.EntityFrameworkCore).最近,我还使用Identity 6.0 (AspNetCore.Identity.EntityFrameworkCore) 创建了 .Net 6 API。

Note : There are some schema related changes in both of this framework, like some additional tables and fields.注意:在这两个框架中都有一些与架构相关的变化,比如一些额外的表和字段。 check snapshot that I added at last.检查我最后添加的快照。

The issue is the common database that I have to manage.问题是我必须管理的公共数据库。

  • I have tried and successfully completed updation of existing database with latest schema.我已经尝试并成功完成了使用最新模式更新现有数据库。
  • I have also migrated the data for the identity tables.我还迁移了身份表的数据。
  • The only issue I face right now is I'm not sure how to support old legacy app going further.我现在面临的唯一问题是我不确定如何进一步支持旧的遗留应用程序。 (I want to have old app as it is, but want it to use new identity tables.) (我想拥有旧的应用程序,但希望它使用新的身份表。)
  • Since the exisiting/old app is in .Net framework 4.6.1, I can not really update identity and it's tables to have latest schema in it.由于现有/旧应用程序位于 .Net 框架 4.6.1 中,因此我无法真正更新身份,并且它的表中包含最新模式。 (I don't mind doing any hack or any fix. old app should work with latest idenitty schema is what imp for me at the moment.) (我不介意做任何黑客或任何修复。旧应用程序应该与最新的身份模式一起工作,这对我来说是重要的。)

Is there any option that I can follow without changing code much, I have tight deadline to follow and I don't really want to create external API to authenticate old legacy app .有没有什么选项可以在不更改代码的情况下遵循,我的截止日期很紧,我真的不想创建外部 API 来验证旧的遗留应用程序 Any help or idea would be really appreciated.任何帮助或想法将不胜感激。

在此处输入图像描述

I didn't find any way to update existing app (.Net standard 4.6) to support new identity structure.我没有找到任何方法来更新现有应用程序(.Net 标准 4.6)以支持新的身份结构。 So here is what I did to resolve this issue.所以这就是我为解决这个问题所做的。

  1. As #Jeremy suggested in comments, I configured my .Net core Identity models to have different names (other then by default, so it does not have any conflict with existing tables) https://docs.microsoft.com/en-us/aspnet/core/security/authentication/customize-identity-model?view=aspnetcore-6.0#change-tablecolumn-names-and-facets (keep order of model configuration as it is as given in thread. I got issues when I kept my base.OnModelCreating(builder); below builder configuration.)正如#Jeremy在评论中所建议的那样,我将我的 .Net 核心身份模型配置为具有不同的名称(默认情况下其他名称,因此它与现有表没有任何冲突) https://docs.microsoft.com/en-us/ aspnet/core/security/authentication/customize-identity-model?view=aspnetcore-6.0#change-tablecolumn-names-and-facets (保持模型配置的顺序与线程中给出的一样。我保留我的base.OnModelCreating(builder);在构建器配置下方。)
  2. I have found a script to create identity tables schema and move records.我找到了一个脚本来创建身份表架构和移动记录。 see below screenshot.见下面的截图。 _New represents the .Net core identity tables scehma. _New表示 .Net 核心标识表 scehma。 I have attached that script here with and I have run this script in common database.我已在此处附加该脚本,并且已在公共数据库中运行此脚本。

在此处输入图像描述

  1. So now I have common database with both old and new identity tables.所以现在我有一个包含新旧身份表的通用数据库。 old application is still pointing and working well with old tables which .Net core identity framework is poiting to new database.旧应用程序仍然指向旧表并与旧表一起工作,而 .Net 核心身份框架指向新数据库。
  2. Since I have moved all the data and records from old tables to new table, I can access them in new idenity app too.由于我已将所有数据和记录从旧表移动到新表,因此我也可以在新的身份应用程序中访问它们。
  3. Till now I have no need to run migration in new app, so I disabled it.到目前为止,我不需要在新应用程序中运行迁移,所以我禁用了它。 but there was concern of what if I run migration and how will it affect existing database.但有人担心如果我运行迁移会如何影响现有数据库。 so I did some R&D and found that we can create migration and before running that migration, we can just comment out the code inside the up and down method.所以我做了一些研发,发现我们可以创建迁移,在运行迁移之前,我们可以在 up 和 down 方法中注释掉代码。 after that we can run this migration and update database.之后,我们可以运行此迁移并更新数据库。 basically empty migration to keep in sync with existing database.基本上是空迁移以与现有数据库保持同步。 (haven't checked this working but this was my idea if I needed it) (尚未检查此工作,但如果我需要,这是我的想法)

Here is the sql Script that I used.这是我使用的 sql 脚本。

STEP 1 : Change name of existing tables第 1 步:更改现有表的名称

EXEC sp_rename 'AspNetRoles', 'AspNetRoles_old';
EXEC sp_rename 'AspNetUserClaims', 'AspNetUserClaims_old';
EXEC sp_rename 'AspNetUserLogins', 'AspNetUserLogins_old';
EXEC sp_rename 'AspNetUserRoles', 'AspNetUserRoles_old';
EXEC sp_rename 'AspNetUsers', 'AspNetUsers_old';

STEP 2 : Create ASP.NET Core Identity tables第 2 步:创建 ASP.NET Core 身份表

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AspNetRoleClaims](
[Id] [int] IDENTITY(1,1) NOT NULL,
[RoleId] [nvarchar](450) NOT NULL,
[ClaimType] [nvarchar](max) NULL,
[ClaimValue] [nvarchar](max) NULL,
 CONSTRAINT [PK_AspNetRoleClaims] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO


SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AspNetRoles](
[Id] [nvarchar](450) NOT NULL,
[Name] [nvarchar](256) NULL,
[NormalizedName] [nvarchar](256) NULL,
[ConcurrencyStamp] [nvarchar](max) NULL,
 CONSTRAINT [PK_AspNetRoles] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO


SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AspNetUserClaims](
[Id] [int] IDENTITY(1,1) NOT NULL,
[UserId] [nvarchar](450) NOT NULL,
[ClaimType] [nvarchar](max) NULL,
[ClaimValue] [nvarchar](max) NULL,
 CONSTRAINT [PK_AspNetUserClaims] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO


SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AspNetUserLogins](
[LoginProvider] [nvarchar](128) NOT NULL,
[ProviderKey] [nvarchar](128) NOT NULL,
[ProviderDisplayName] [nvarchar](max) NULL,
[UserId] [nvarchar](450) NOT NULL,
 CONSTRAINT [PK_AspNetUserLogins] PRIMARY KEY CLUSTERED
(
[LoginProvider] ASC,
[ProviderKey] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO


SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AspNetUserRoles](
[UserId] [nvarchar](450) NOT NULL,
[RoleId] [nvarchar](450) NOT NULL,
 CONSTRAINT [PK_AspNetUserRoles] PRIMARY KEY CLUSTERED
(
[UserId] ASC,
[RoleId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO


SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AspNetUsers](
[Id] [nvarchar](450) NOT NULL,
[UserName] [nvarchar](256) NULL,
[NormalizedUserName] [nvarchar](256) NULL,
[Email] [nvarchar](256) NULL,
[NormalizedEmail] [nvarchar](256) NULL,
[EmailConfirmed] [bit] NOT NULL,
[PasswordHash] [nvarchar](max) NULL,
[SecurityStamp] [nvarchar](max) NULL,
[ConcurrencyStamp] [nvarchar](max) NULL,
[PhoneNumber] [nvarchar](max) NULL,
[PhoneNumberConfirmed] [bit] NOT NULL,
[TwoFactorEnabled] [bit] NOT NULL,
[LockoutEnd] [datetimeoffset](7) NULL,
[LockoutEnabled] [bit] NOT NULL,
[AccessFailedCount] [int] NOT NULL,
 CONSTRAINT [PK_AspNetUsers] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO


SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AspNetUserTokens](
[UserId] [nvarchar](450) NOT NULL,
[LoginProvider] [nvarchar](128) NOT NULL,
[Name] [nvarchar](128) NOT NULL,
[Value] [nvarchar](max) NULL,
 CONSTRAINT [PK_AspNetUserTokens] PRIMARY KEY CLUSTERED
(
[UserId] ASC,
[LoginProvider] ASC,
[Name] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO


CREATE NONCLUSTERED INDEX [IX_AspNetRoleClaims_RoleId] ON [dbo].[AspNetRoleClaims]
(
[RoleId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO


CREATE UNIQUE NONCLUSTERED INDEX [RoleNameIndex] ON [dbo].[AspNetRoles]
(
[NormalizedName] ASC
)
WHERE ([NormalizedName] IS NOT NULL)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO


CREATE NONCLUSTERED INDEX [IX_AspNetUserClaims_UserId] ON [dbo].[AspNetUserClaims]
(
[UserId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO


CREATE NONCLUSTERED INDEX [IX_AspNetUserLogins_UserId] ON [dbo].[AspNetUserLogins]
(
[UserId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO


CREATE NONCLUSTERED INDEX [IX_AspNetUserRoles_RoleId] ON [dbo].[AspNetUserRoles]
(
[RoleId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO


CREATE NONCLUSTERED INDEX [EmailIndex] ON [dbo].[AspNetUsers]
(
[NormalizedEmail] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO


CREATE UNIQUE NONCLUSTERED INDEX [UserNameIndex] ON [dbo].[AspNetUsers]
(
[NormalizedUserName] ASC
)
WHERE ([NormalizedUserName] IS NOT NULL)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE [dbo].[AspNetRoleClaims]  WITH CHECK ADD  CONSTRAINT [FK_AspNetRoleClaims_AspNetRoles_RoleId] FOREIGN KEY([RoleId])
REFERENCES [dbo].[AspNetRoles] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[AspNetRoleClaims] CHECK CONSTRAINT [FK_AspNetRoleClaims_AspNetRoles_RoleId]
GO
ALTER TABLE [dbo].[AspNetUserClaims]  WITH CHECK ADD  CONSTRAINT [FK_AspNetUserClaims_AspNetUsers_UserId] FOREIGN KEY([UserId])
REFERENCES [dbo].[AspNetUsers] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[AspNetUserClaims] CHECK CONSTRAINT [FK_AspNetUserClaims_AspNetUsers_UserId]
GO
ALTER TABLE [dbo].[AspNetUserLogins]  WITH CHECK ADD  CONSTRAINT [FK_AspNetUserLogins_AspNetUsers_UserId] FOREIGN KEY([UserId])
REFERENCES [dbo].[AspNetUsers] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[AspNetUserLogins] CHECK CONSTRAINT [FK_AspNetUserLogins_AspNetUsers_UserId]
GO
ALTER TABLE [dbo].[AspNetUserRoles]  WITH CHECK ADD  CONSTRAINT [FK_AspNetUserRoles_AspNetRoles_RoleId] FOREIGN KEY([RoleId])
REFERENCES [dbo].[AspNetRoles] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[AspNetUserRoles] CHECK CONSTRAINT [FK_AspNetUserRoles_AspNetRoles_RoleId]
GO
ALTER TABLE [dbo].[AspNetUserRoles]  WITH CHECK ADD  CONSTRAINT [FK_AspNetUserRoles_AspNetUsers_UserId] FOREIGN KEY([UserId])
REFERENCES [dbo].[AspNetUsers] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[AspNetUserRoles] CHECK CONSTRAINT [FK_AspNetUserRoles_AspNetUsers_UserId]
GO
ALTER TABLE [dbo].[AspNetUserTokens]  WITH CHECK ADD  CONSTRAINT [FK_AspNetUserTokens_AspNetUsers_UserId] FOREIGN KEY([UserId])
REFERENCES [dbo].[AspNetUsers] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[AspNetUserTokens] CHECK CONSTRAINT [FK_AspNetUserTokens_AspNetUsers_UserId]
GO

STEP 3 : Migrate data from old tables (ASP.NET Identity) to new tables (ASP.NET Core Identity)第 3 步:将数据从旧表 (ASP.NET Identity) 迁移到新表 (ASP.NET Core Identity)

INSERT INTO AspNetRoles ([Id], [Name], [NormalizedName], [ConcurrencyStamp])
SELECT [Id], [Name], UPPER([Name]), LOWER(NEWID()) FROM Objectra_Development.dbo.AspNetRoles

INSERT INTO AspNetUsers ([Id], [UserName], [NormalizedUserName], [Email], [NormalizedEmail], [EmailConfirmed], [PasswordHash], [SecurityStamp], [ConcurrencyStamp], [PhoneNumber], [PhoneNumberConfirmed], [TwoFactorEnabled], [LockoutEnd], [LockoutEnabled], [AccessFailedCount], 
AssignObjects, AccessOwnObjectsOnly, UserObjectId, UserObjectDefd, GoogleAuth, LastPasswordResetDate, FriendlyName, AccessibleObjectDefinitions)
SELECT [Id], [UserName], UPPER([UserName]), [Email], UPPER([Email]), [EmailConfirmed], [PasswordHash], [SecurityStamp], LOWER(NEWID()), [PhoneNumber], [PhoneNumberConfirmed], 0, null, 1, 0, 
AssignObjects, AccessOwnObjectsOnly, UserObjectId, UserObjectDefd, GoogleAuth, LastPasswordResetDate, FriendlyName, AccessibleObjectDefinitions
FROM Objectra_Development.dbo.AspNetUsers;

INSERT INTO AspNetUserRoles ([UserId], [RoleId])
SELECT [UserId], [RoleId] 
FROM Objectra_Development.dbo.AspNetUserRoles;

I faced the same problem and ended up creating new identity core tables using a schema.我遇到了同样的问题,最终使用模式创建了新的身份核心表。

builder.ToTable(name: "Users", "Identity");
builder.ToTable(name: "Roles", "Identity");
builder.ToTable(name: "UserRoles", "Identity");
builder.ToTable(name: "UserClaims", "Identity");
builder.ToTable(name: "UserLogins", "Identity");
builder.ToTable(name: "UserTokens", "Identity");
builder.ToTable(name: "RoleClaims", "Identity");

Then I used a trigger on the old identity users table to keep the new identity users table in sync.然后我在旧的身份用户表上使用了一个触发器来保持新的身份用户表同步。

CREATE/*ALTER*/ TRIGGER [dbo].[IdentityUsers_Sync] ON [dbo].[Users] 
AFTER INSERT, UPDATE AS 
BEGIN
    --INSERT
    IF NOT EXISTS (SELECT * FROM deleted)
        BEGIN
            INSERT INTO [Identity].[Users] 
            (
                Id,
                UserName,
                NormalizedUserName,
                Email,
                NormalizedEmail,
                EmailConfirmed,
                PasswordHash,
                SecurityStamp,
                PhoneNumber,
                PhoneNumberConfirmed,
                TwoFactorEnabled,
                LockoutEnabled,
                AccessFailedCount
            )
            SELECT
                Id,
                UserName,
                UPPER(UserName),
                Email,
                UPPER(Email),
                EmailConfirmed,
                PasswordHash,
                SecurityStamp,
                PhoneNumber,
                PhoneNumberConfirmed,
                TwoFactorEnabled,
                0,
                0
            FROM inserted
        END
    --UPDATE
    IF EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted)
        BEGIN
            UPDATE iu
            SET 
                iu.UserName = i.UserName,
                iu.NormalizedUserName = UPPER(i.UserName),
                iu.Email = i.Email,
                iu.NormalizedEmail = UPPER(i.Email),
                iu.EmailConfirmed = i.EmailConfirmed,
                iu.PasswordHash = i.PasswordHash,
                iu.SecurityStamp = i.SecurityStamp,
                iu.PhoneNumber = i.PhoneNumber,
                iu.PhoneNumberConfirmed = i.PhoneNumberConfirmed,
                iu.TwoFactorEnabled = i.TwoFactorEnabled,
                iu.LockoutEnabled = 0,
                iu.AccessFailedCount = 0
            FROM [Identity].[Users] iu, inserted i
            WHERE iu.Id = i.Id
        END
END
GO
ALTER TABLE [dbo].[Users] ENABLE TRIGGER [IdentityUsers_Sync]
GO

And my plan is to create an api controller in the legacy system to handle new registrations (via HttpClient in any new Core apps).我的计划是在遗留系统中创建一个 api 控制器来处理新注册(通过任何新核心应用程序中的 HttpClient)。 Then the trigger will pick it up and keep the new system in sync.然后触发器将拾取它并保持新系统同步。

Having the legacy system use the new identity tables doesn't look like an option at this point.让遗留系统使用新的身份表在这一点上看起来不是一个选项。 Maybe additional fields could be added to the new schema and use a trigger to fill them in?也许可以将其他字段添加到新架构中并使用触发器来填充它们? Haven't tried that.没试过。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 .net 标准库在 .net 核心中失败,但在框架中失败 - .net standard library fails in .net core but not in framework .net核心和身份框架的集成测试 - integration testing with .net core and identity framework .Net Core Identity Framework 通过声明获取用户 - .Net Core Identity Framework Get Users By Claim 在.net核心和.net框架中使用.net标准包 - Using a .net standard package in .net core and .net framework 在 2 个 .NET Core 应用程序 DataProtectionProvider 之间共享 cookie - Sharing cookies between 2 .NET Core Applications DataProtectionProvider 如何使用.NET Standard和Entity Framework Core为现有数据库创建Entity Framework edmx文件? - How to create an Entity Framework edmx file for an existing database with .NET Standard and Entity Framework Core? ASP.NET核心2.2:在框架类之间共享特定于请求的数据最安全的方法是什么? - ASP.NET core 2.2: what is the safest way of sharing request-specific data between framework classes? 在 ASP.NET Core 2.2 和 ASP 之间共享 Cookie 身份验证。 NET MVC 5 (.NET Framework 4.6.1) 没有 Microsoft.Identity - Share Cookie authentication between ASP.NET Core 2.2 and ASP. NET MVC 5 (.NET Framework 4.6.1) without Microsoft.Identity CultureInfo 在 .NET 核心和 .NET 框架之间有所不同 - CultureInfo differs between .NET Core and .NET Framework 在不同的.NET平台(UWP,.Net Core)之间共享代码和类 - Sharing Code and Classes between different .NET Platform (UWP, .Net Core)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM