@@ -329,25 +329,26 @@ dotnet aspnet-codegenerator identity --dbContext FrontEnd.Data.IdentityDbContext
329
329
330
330
public async Task <List <SessionResponse >> GetSessionsByAttendeeAsync (string name )
331
331
{
332
- // TODO: Would be better to add backend API for this
332
+ var response = await _httpClient . GetAsync ( $" /api/attendees/{ name }/sessions " );
333
333
334
- var sessionsTask = GetSessionsAsync ();
335
- var attendeeTask = GetAttendeeAsync (name );
336
-
337
- await Task .WhenAll (sessionsTask , attendeeTask );
338
-
339
- var sessions = await sessionsTask ;
340
- var attendee = await attendeeTask ;
341
-
342
- if (attendee == null )
343
- {
344
- return new List <SessionResponse >();
345
- }
346
-
347
- var sessionIds = attendee .Sessions .Select (s => s .Id );
348
-
349
- sessions .RemoveAll (s => ! sessionIds .Contains (s .Id ));
334
+ response .EnsureSuccessStatusCode ();
350
335
336
+ return await response .Content .ReadAsAsync <List <SessionResponse >>();
337
+ }
338
+ ```
339
+ ### Add the BackEnd API to get sessions by an attendee
340
+ 1. Add an action called `GetSessions` to the `AttendeesController` in the `BackEnd` project:
341
+ ```c#
342
+ [HttpGet (" {username}/sessions" )]
343
+ public async Task <ActionResult <List <SessionResponse >>> GetSessions (string username )
344
+ {
345
+ var sessions = await _db .Sessions .AsNoTracking ()
346
+ .Include (s => s .Track )
347
+ .Include (s => s .SessionSpeakers )
348
+ .ThenInclude (ss => ss .Speaker )
349
+ .Where (s => s .SessionAttendees .Any (sa => sa .Attendee .UserName == username ))
350
+ .Select (m => m .MapSessionResponse ())
351
+ .ToListAsync ();
351
352
return sessions ;
352
353
}
353
354
```
@@ -361,9 +362,12 @@ dotnet aspnet-codegenerator identity --dbContext FrontEnd.Data.IdentityDbContext
361
362
1. Compute the value of that property in `OnGetAsync`:
362
363
363
364
```csharp
364
- var sessions = await _apiClient .GetSessionsByAttendeeAsync (User .Identity .Name );
365
+ if (User.Identity.IsAuthenticated)
366
+ {
367
+ var sessions = await _apiClient .GetSessionsByAttendeeAsync (User .Identity .Name );
365
368
366
- IsInPersonalAgenda = sessions .Any (s => s .Id == id );
369
+ IsInPersonalAgenda = sessions .Any (s => s .Id == id );
370
+ }
367
371
```
368
372
1. Add a form to the bottom of `Session.cshtml` razor page that adds the ability to add/remove the session to the attendee's personal agenda:
369
373
@@ -470,70 +474,37 @@ dotnet aspnet-codegenerator identity --dbContext FrontEnd.Data.IdentityDbContext
470
474
}
471
475
}
472
476
```
473
- 1 . Add the HTML to render the list of sessions on the attendee 's personal agenda to `MyAgenda.cshtml`:
474
-
477
+ 1 . Refactor the `Index .cshtml ` into a `_AgendaPartial .cshtml ` under the `Pages \Shared ` folder . It should have the following content :
475
478
```html
476
- @page
477
- @model MyAgendaModel
478
- @{
479
- ViewData [" Title" ] = " My Agenda" ;
480
- }
481
-
482
- @if (Model .ShowMessage )
483
- {
484
- < div class = " alert alert-success alert-dismissible" role = " alert" >
485
- < button type = " button" class = " close" data - dismiss = " alert" aria - label = " Close" >< span aria - hidden = " true" > & times ;< / span > < / button >
486
- @Model .Message
487
- < / div >
488
- }
479
+ @model IndexModel
489
480
490
481
< div class = " agenda" >
491
- < h1 > My Conference @System .DateTime .Now .Year < / h1 >
492
-
493
- @if (Model .UserSessions .Count == 0 )
494
- {
495
- < p >
496
- You have not yet added any sessions to your agenda . Add sessions to your personal agenda
497
- by browsing the < a asp - page = " /Index" > conference agenda < / a > or < a asp - page = " /Search" > searching < / a >
498
- for sessions and speakers and clicking the star button .
499
- < / p >
500
- }
501
-
502
- < ul class = " nav nav-pills" >
503
- @foreach (var day in Model .DayOffsets )
504
- {
505
- < li role = " presentation" class = " @(Model.CurrentDayOffset == day.Offset ? " active " : null)" >
506
- < a asp - route - day = " @day.Offset" > @day .DayofWeek ? .ToString ()< / a >
507
- < / li >
508
- }
509
- < / ul >
510
-
511
482
@foreach (var timeSlot in Model .Sessions )
512
483
{
513
484
< h4 > @timeSlot .Key ? .ToString (" HH:mm" )< / h4 >
514
485
< div class = " row" >
515
486
@foreach (var session in timeSlot )
516
487
{
517
- < div class = " col-md-3 mb-4" >
518
- < div class = " card shadow session h-100" >
519
- < div class = " card-header" > @session .Track ?.Name < / div >
520
- < div class = " card-body" >
521
- < h5 class = " card-title" >< a asp - page = " Session" asp - route - id = " @session.ID " > @session .Title < / a >< / h5 >
522
- < / div >
523
- < div class = " card-footer" >
524
- < ul class = " list-inline mb-0" >
525
- @foreach (var speaker in session .Speakers )
526
- {
527
- < li class = " list-inline-item" >
528
- < a asp - page = " Speaker" asp - route - id = " @speaker.Id" > @speaker .Name < / a >
529
- < / li >
530
- }
531
- < / ul >
532
- < form authz = " true " method = " post" >
488
+ < div class = " col-md-3 mb-4" >
489
+ < div class = " card shadow session h-100" >
490
+ < div class = " card-header" > @session .Track ?.Name < / div >
491
+ < div class = " card-body" >
492
+ < h5 class = " card-title" >< a asp - page = " Session" asp - route - id = " @session.Id " > @session .Title < / a >< / h5 >
493
+ < / div >
494
+ < div class = " card-footer" >
495
+ < ul class = " list-inline mb-0" >
496
+ @foreach (var speaker in session .Speakers )
497
+ {
498
+ < li class = " list-inline-item" >
499
+ < a asp - page = " Speaker" asp - route - id = " @speaker.Id" > @speaker .Name < / a >
500
+ < / li >
501
+ }
502
+ < / ul >
503
+ < form authz method = " post" >
533
504
< input type = " hidden" name = " sessionId" value = " @session.Id" / >
534
505
< p class = " mb-0" >
535
- < a authz - policy = " Admin" asp - page = " /Admin/EditSession" asp - route - id = " @session.Id" class = " btn btn-default btn-sm " > Edit < / a >
536
- @if (Model .UserSessions .Contains (session .ID ))
506
+ < a authz - policy = " Admin" asp - page = " /Admin/EditSession" asp - route - id = " @session.Id" class = " btn btn-default btn-xs " > Edit < / a >
507
+ @if (Model .UserSessions .Contains (session .Id ))
537
508
{
538
509
< button type = " submit" asp - page - handler = " Remove" class = " btn btn-default btn-sm bg-transparent" title = " Remove from my personal agenda" >
539
510
< i class = " icon ion-md-star" aria - hidden = " true" >< / i >
@@ -546,15 +517,41 @@ dotnet aspnet-codegenerator identity --dbContext FrontEnd.Data.IdentityDbContext
546
517
< / button >
547
518
}
548
519
< / p >
549
- < / form >
520
+ < / form >
521
+ < / div >
550
522
< / div >
551
523
< / div >
552
- < / div >
553
524
}
554
525
< / div >
555
526
}
556
527
< / div >
557
528
```
529
+ 1 . Update the `Index .cshtml ` to use the new `_AgendaPartial `. Replace the entire div with the " agenda" css class and replace it with the following :
530
+ ```html
531
+ < h1 class = " mb-4" > My Conference @System .DateTime .Now .Year < / h1 >
532
+
533
+ < partial name = " _AgendaPartial" model = " Model" / >
534
+ ```
535
+ 1 . Next , use the `_AgendaPartial ` on the `MyAgenda .cshtml ` page .
536
+ ```html
537
+ @page
538
+ @model MyAgendaModel
539
+ @{
540
+ ViewData [" Title" ] = " My Agenda" ;
541
+ }
542
+
543
+ @if (Model .ShowMessage )
544
+ {
545
+ < div class = " alert alert-success alert-dismissible" role = " alert" >
546
+ < button type = " button" class = " close" data - dismiss = " alert" aria - label = " Close" >< span aria - hidden = " true" > & times ;< / span >< / button >
547
+ @Model .Message
548
+ < / div >
549
+ }
550
+
551
+ < h1 class = " mb-4" > My Agenda - My Conference @System .DateTime .Now .Year < / h1 >
552
+
553
+ < partial name = " _AgendaPartial" model = " Model" / >
554
+ ```
558
555
559
556
## Add the My Agenda link to the Layout
560
557
1 . Go to the layout file `_Layout .cshtml `.
@@ -581,50 +578,45 @@ dotnet aspnet-codegenerator identity --dbContext FrontEnd.Data.IdentityDbContext
581
578
< / li >
582
579
< / ul >
583
580
< / div >
584
- ```
585
- 1 . Add a `[TempData ]` backed `Message ` property to `IndexModel `, similar to the property we added to the `EditSession ` page :
586
- ```csharp
587
- [TempData ]
588
- public string Message { get ; set ; }
589
-
590
- public bool ShowMessage => ! string .IsNullOrEmpty (Message );
591
- ```
581
+ ```
592
582
1 . You should be able to login as an attendee , add / remove sessions to your personal agenda and click on MyAgenda to have them show up .
593
583
594
584
## Update IndexModel to include User Sessions
595
585
1 . Add a `UserSessions ` property to the `IndexModel `:
596
586
```csharp
597
- public List < int > UserSessions { get ; set ; }
598
- ```
587
+ public List < int > UserSessions { get ; set ; } = new List < int >();
588
+ ```
599
589
1 . Update the `OnGet ` method to fetch the `UserSessions `:
600
590
601
591
```csharp
602
592
public async Task OnGet (int day = 0 )
603
593
{
604
594
CurrentDayOffset = day ;
605
595
606
- var userSessions = await _apiClient .GetSessionsByAttendeeAsync (User .Identity .Name );
607
- UserSessions = userSessions .Select (u => u .Id ).ToList ();
596
+ if (User .Identity .IsAuthenticated )
597
+ {
598
+ var userSessions = await _apiClient .GetSessionsByAttendeeAsync (User .Identity .Name );
599
+ UserSessions = userSessions .Select (u => u .Id ).ToList ();
600
+ }
608
601
609
602
var sessions = await GetSessionsAsync ();
610
603
// ...
611
604
```
612
605
1 . Add the following two methods to the `IndexModel ` to handle adding and removing sessions from your agenda fron the `Index ` page :
613
606
```csharp
614
-
615
- public async Task < IActionResult > OnPostAsync (int sessionId )
616
- {
617
- await _apiClient .AddSessionToAttendeeAsync (User .Identity .Name , sessionId );
607
+ public async Task < IActionResult > OnPostAsync (int sessionId )
608
+ {
609
+ await _apiClient .AddSessionToAttendeeAsync (User .Identity .Name , sessionId );
618
610
619
- return RedirectToPage ();
620
- }
611
+ return RedirectToPage ();
612
+ }
621
613
622
- public async Task < IActionResult > OnPostRemoveAsync (int sessionId )
623
- {
624
- await _apiClient .RemoveSessionFromAttendeeAsync (User .Identity .Name , sessionId );
614
+ public async Task < IActionResult > OnPostRemoveAsync (int sessionId )
615
+ {
616
+ await _apiClient .RemoveSessionFromAttendeeAsync (User .Identity .Name , sessionId );
625
617
626
- return RedirectToPage ();
627
- }
618
+ return RedirectToPage ();
619
+ }
628
620
```
629
621
1 . Run the application and test logging in and managing your agenda from the `Index ` page , individual session details , and from the `My Agenda ` page .
630
622
0 commit comments