Angular 从.net core获取广告用户信息时出现问题
我的应用程序由两个独立的项目组成:一个.NET核心后端 和一个有角度的前端 我已经成功地添加了windows AD身份验证,我正在Angular应用程序中获取用户信息,但只有在刷新页面之后 打开第一页时,我的用户为空Angular 从.net core获取广告用户信息时出现问题,angular,asp.net-core,active-directory,Angular,Asp.net Core,Active Directory,我的应用程序由两个独立的项目组成:一个.NET核心后端 和一个有角度的前端 我已经成功地添加了windows AD身份验证,我正在Angular应用程序中获取用户信息,但只有在刷新页面之后 打开第一页时,我的用户为空 ERROR TypeError: Cannot read property 'name' of null 刷新后,我能够获得用户信息。实际发生了什么,我应该如何解决这个问题 public Task < AdUser > GetAdUser(Guid guid) {
ERROR TypeError: Cannot read property 'name' of null
刷新后,我能够获得用户信息。实际发生了什么,我应该如何解决这个问题
public Task < AdUser > GetAdUser(Guid guid) {
return Task.Run(() => {
try {
PrincipalContext context = new PrincipalContext(ContextType.Domain);
UserPrincipal principal = new UserPrincipal(context);
if (context != null) {
principal = UserPrincipal.FindByIdentity(context, IdentityType.Guid,
guid.ToString());
}
return AdUser.CastToAdUser(principal);
} catch (Exception ex) {
throw new Exception("Error retrieving AD User", ex);
}
});
}
app.component.rs
top-navigation.component.ts
最后,我在顶部导航组件中获取用户数据,因为我需要在其中显示名字和姓氏
编辑:添加新代码
app-routing.module.ts
app.component.ts
top-navigation.component.ts
编辑:最终解决方案
app-routing.module.ts
好的,我会试着解释这一切是如何运作的。您的问题是,在localStorage尝试获取数据之后,组件中的getCurrentUser会执行 如果您的AppComponent是应用程序的根组件,top navigation组件在应用程序组件html中声明,那么您需要在AppComponent启动之前确保数据在那里 因此,所发生的是(一个可能的时间线,因为javascript的异步性质意味着有时某些步骤将以不同的顺序执行):
@Injectable()
export class AuthGuard implements CanActivate {
constructor(
private adUserService: ADUserService,
private router: Router
) {}
canActivate(next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> {
// We will return a true if the user is logged in
// or false otherwise
return this.adUserService.login().pipe(
map((x) => {
// Since my service returned succesfully I will set the
// locale storage with the appropriate data
localStorage.setItem('user', JSON.stringify(x));
// I will also return true to let the router module
// know that it can proceed
return true;
}),
catchError(() => {
// If there was an error, I will return false, so the
// router module will not allow the transition
// if I want to, I can add the router module to transition
// to a login page
return of(false)
})
);
}
}
@Injectable()
导出类AuthGuard实现了CanActivate{
建造师(
私人adUserService:adUserService,
专用路由器
) {}
canActivate(下一步:ActivatedRouteSnapshot,
状态:RouterStateSnapshot):可观察{
//如果用户登录,我们将返回true
//否则就错了
返回此.adUserService.login()管道(
地图((x)=>{
//既然我的服务成功返回,我将设置
//具有适当数据的区域设置存储
setItem('user',JSON.stringify(x));
//我还将返回true,让路由器模块
//知道它可以继续
返回true;
}),
捕获错误(()=>{
//如果有错误,我将返回false,因此
//路由器模块将不允许转换
//如果我想,我可以将路由器模块添加到transition
//转到登录页面
返回(假)
})
);
}
}
您可以在此处查看完整的解决方案:
要查看正在运行的区域设置存储,请尝试url。重新措辞并格式化代码段感谢提供的解决方案。我已经设置了Guard服务,我在其中检查用户对象是否为null,但我不知道如果它为null该怎么办。。。你说“如果数据在那里,那么转到应用程序组件,警卫将确保你在本地存储中有ADUser数据”,如何继续和不继续转到主应用程序组件。。。希望你明白我的意思,我当然明白。检查stackblitz url以获取完整解决方案。我没有包括顶部导航。如果答案对你有帮助,一定要投赞成票。对不起,我对此有一些问题,即使你的stackblitz演示也很好。。。在我的代码中,我的应用程序总是进入CanActivate,并试图通过this.adUserService.login()获取数据,但出于某种原因,我的顶部导航正在尝试呈现数据,当然用户为空。原因是什么?请记住,我正在top-navigation.component.ts中的ngOnInit下调用“this.user=JSON.parse(localStorage.getItem('user')”),但显然它是空的。。。我还需要使用解析器吗?能否在代码中共享路由器配置和AppComponent/TopNavigation?我已用您要求的代码更新了我的问题。
this.identityService.getCurrentUser()
.subscribe(res => {
localStorage.setItem('user', JSON.stringify(res));
});
user = JSON.parse(localStorage.getItem('user'));
const appRoutes: Routes = [
{
path: 'home',
component: HomeComponent,
data: { title: 'Home' },
canActivate: [AuthGuardService]
},
{
path: 'history',
component: HistoryComponent,
data: { title: 'History' }
},
{
path: '404',
component: NotFoundErrorComponent,
data: { title: 'Error 404' }
},
{
path: '',
component: HomeComponent,
pathMatch: 'full'
},
{
path: '**',
redirectTo: '/404',
pathMatch: 'full',
data: { title: 'Error 404' }
}
];
@NgModule({
imports: [RouterModule.forRoot(appRoutes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
title = 'Home';
constructor(private titleService: Title,
private router: Router,
private activatedRoute: ActivatedRoute { }
ngOnInit() {
this.router.events.pipe(
filter(event => event instanceof NavigationEnd),
map(() => this.activatedRoute),
map((route) => {
while (route.firstChild) { route = route.firstChild; }
return route;
}),
filter((route) => route.outlet === 'primary'),
mergeMap((route) => route.data))
.subscribe((event) => this.titleService.setTitle(event.title));
}
}
export class TopNavigationComponent implements OnInit {
constructor(private router: Router) { }
user;
ngOnInit() {
this.user = JSON.parse(localStorage.getItem('user'));
}
}
const appRoutes: Routes = [
{
path: '',
component: TopNavComponent,
resolve: { userData: IdentityResolverService },
children: [
{
path: 'home',
component: HomeComponent,
data: { title: 'Home' },
canActivate: [AuthGuardService]
},
{
path: 'history',
component: HistoryComponent,
data: { title: 'History' },
canActivate: [AuthGuardService]
},
{
path: '404',
component: NotFoundErrorComponent,
data: { title: 'Error 404' },
canActivate: [AuthGuardService]
},
{
path: '',
redirectTo: 'home',
pathMatch: 'full',
canActivate: [AuthGuardService]
},
{
path: '**',
redirectTo: '/404',
pathMatch: 'full',
data: { title: 'Error 404' },
canActivate: [AuthGuardService]
}
]
};
]
@Injectable()
export class AuthGuard implements CanActivate {
constructor(
private adUserService: ADUserService,
private router: Router
) {}
canActivate(next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> {
// We will return a true if the user is logged in
// or false otherwise
return this.adUserService.login().pipe(
map((x) => {
// Since my service returned succesfully I will set the
// locale storage with the appropriate data
localStorage.setItem('user', JSON.stringify(x));
// I will also return true to let the router module
// know that it can proceed
return true;
}),
catchError(() => {
// If there was an error, I will return false, so the
// router module will not allow the transition
// if I want to, I can add the router module to transition
// to a login page
return of(false)
})
);
}
}