Skip to content
This repository was archived by the owner on Jul 10, 2024. It is now read-only.

Commit 3d4be5b

Browse files
davidfowlDamianEdwards
authored andcommitted
Updated session5
1 parent 4cd1c51 commit 3d4be5b

File tree

1 file changed

+76
-77
lines changed

1 file changed

+76
-77
lines changed

docs/5. Add personal agenda.md

Lines changed: 76 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -140,133 +140,132 @@ In this section we'll add features that track attendees who have registered on t
140140
[DataType(DataType.EmailAddress)]
141141
public override string EmailAddress { get => base.EmailAddress; set => base.EmailAddress = value; }
142142
}
143-
}
143+
}
144144
```
145145
1. In `Welcome.cshtml.cs`, add logic that associates the logged in user with an attendee:
146146
```csharp
147-
using System.Threading.Tasks;
148-
using FrontEnd.Services;
149-
using FrontEnd.Pages.Models;
150-
using Microsoft.AspNetCore.Mvc;
151-
using Microsoft.AspNetCore.Mvc.RazorPages;
152-
using System.Security.Claims;
153-
using Microsoft.AspNetCore.Authentication;
154-
using Microsoft.AspNetCore.Identity;
155-
156-
namespace FrontEnd
147+
using System.Threading.Tasks;
148+
using FrontEnd.Services;
149+
using FrontEnd.Pages.Models;
150+
using Microsoft.AspNetCore.Mvc;
151+
using Microsoft.AspNetCore.Mvc.RazorPages;
152+
using System.Security.Claims;
153+
using Microsoft.AspNetCore.Authentication;
154+
using Microsoft.AspNetCore.Identity;
155+
156+
namespace FrontEnd
157+
{
158+
public class WelcomeModel : PageModel
157159
{
158-
public class WelcomeModel : PageModel
160+
private readonly IApiClient _apiClient;
161+
162+
public WelcomeModel(IApiClient apiClient)
159163
{
160-
private readonly IApiClient _apiClient;
164+
_apiClient = apiClient;
165+
}
161166

162-
public WelcomeModel(IApiClient apiClient)
163-
{
164-
_apiClient = apiClient;
165-
}
167+
[BindProperty]
168+
public Attendee Attendee { get; set; }
166169

167-
[BindProperty]
168-
public Attendee Attendee { get; set; }
170+
public IActionResult OnGet()
171+
{
172+
// Redirect to home page if user is anonymous or already registered as attendee
173+
var isAttendee = User.IsAttendee();
169174

170-
public IActionResult OnGet()
175+
if (!User.Identity.IsAuthenticated || isAttendee)
171176
{
172-
// Redirect to home page if user is anonymous or already registered as attendee
173-
var isAttendee = User.IsAttendee();
177+
return RedirectToPage("/Index");
178+
}
174179

175-
if (!User.Identity.IsAuthenticated || isAttendee)
176-
{
177-
return RedirectToPage("/Index");
178-
}
180+
return Page();
181+
}
179182

180-
return Page();
181-
}
183+
public async Task<IActionResult> OnPostAsync()
184+
{
185+
var success = await _apiClient.AddAttendeeAsync(Attendee);
182186

183-
public async Task<IActionResult> OnPostAsync()
187+
if (!success)
184188
{
185-
var success = await _apiClient.AddAttendeeAsync(Attendee);
186-
187-
if (!success)
188-
{
189-
ModelState.AddModelError("", "There was an issue creating the attendee for this user.");
190-
return Page();
191-
}
189+
ModelState.AddModelError("", "There was an issue creating the attendee for this user.");
190+
return Page();
191+
}
192192

193-
// Re-issue the auth cookie with the new IsAttendee claim
194-
User.MakeAttendee();
195-
await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, User);
193+
// Re-issue the auth cookie with the new IsAttendee claim
194+
User.MakeAttendee();
195+
await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, User);
196196

197-
return RedirectToPage("/Index");
198-
}
197+
return RedirectToPage("/Index");
199198
}
200199
}
200+
}
201201
```
202202
1. Logged in users can now be associated with an attendee by visiting this page.
203203

204-
## Add a filter to force logged in users to sign up on welcome page
205-
1. Add a folder called `Filters`.
204+
## Add a middleware to force logged in users to sign up on welcome page
205+
1. Add a folder called `Middleware`.
206206
1. Add a new attribute `SkipWelcomeAttribute.cs` to allow certain pages or action methods to be skipped from enforcing redirection to the Welcome page:
207207

208208
```csharp
209209
using System;
210-
using Microsoft.AspNetCore.Mvc.Filters;
211210

212-
namespace FrontEnd.Filters
211+
namespace FrontEnd
213212
{
214213
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
215-
public class SkipWelcomeAttribute : Attribute, IFilterMetadata
214+
public class SkipWelcomeAttribute : Attribute
216215
{
217216

218217
}
219218
}
220219
```
221-
1. Add a new class called `RequireLoginFilter.cs` that redirects to the Welcome page if the user is authenticated but not associated with an attendee (does not have the `"IsAttendee"` claim):
220+
1. Add a new class called `RequireLoginMiddleware.cs` that redirects to the Welcome page if the user is authenticated but not associated with an attendee (does not have the `"IsAttendee"` claim):
222221

223222
```csharp
224-
public class RequireLoginFilter : IAsyncResourceFilter
223+
public class RequireLoginMiddleware
225224
{
226-
private readonly IUrlHelperFactory _urlHelperFactory;
225+
private readonly RequestDelegate _next;
226+
private readonly LinkGenerator _linkGenerator;
227227

228-
public RequireLoginFilter(IUrlHelperFactory urlHelperFactory)
228+
public RequireLoginMiddleware(RequestDelegate next, LinkGenerator linkGenerator)
229229
{
230-
_urlHelperFactory = urlHelperFactory;
230+
_next = next;
231+
_linkGenerator = linkGenerator;
231232
}
232233

233-
public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
234+
public Task Invoke(HttpContext context)
234235
{
235-
var urlHelper = _urlHelperFactory.GetUrlHelper(context);
236+
var endpoint = context.GetEndpoint();
236237

237238
// If the user is authenticated but not a known attendee *and* we've not marked this page
238239
// to skip attendee welcome, then redirect to the Welcome page
239-
if (context.HttpContext.User.Identity.IsAuthenticated &&
240-
!context.Filters.OfType<SkipWelcomeAttribute>().Any())
240+
if (context.User.Identity.IsAuthenticated &&
241+
endpoint?.Metadata.GetMetadata<SkipWelcomeAttribute>() == null)
241242
{
242-
var isAttendee = context.HttpContext.User.IsAttendee();
243+
var isAttendee = context.User.IsAttendee();
243244

244245
if (!isAttendee)
245246
{
247+
var url = _linkGenerator.GetUriByPage(context, page: "/Welcome");
246248
// No attendee registerd for this user
247-
context.HttpContext.Response.Redirect(urlHelper.Page("/Welcome"));
249+
context.Response.Redirect(url);
248250

249-
return;
251+
return Task.CompletedTask;
250252
}
251253
}
252254

253-
await next();
255+
return _next(context);
254256
}
255257
}
256258
```
257-
1. Register the `RequireLogin` filter globally with MVC using its options in the `ConfigureServices` method in `Startup.cs`:
259+
1. Add the `RequireLoginMiddleware` in `Configure` method in `Startup.cs` before `UseEndpoints()`:
258260

259261
```csharp
260-
services.AddMvc(options =>
262+
app.UseMiddleware<RequireLoginMiddleware>();
263+
264+
app.UseEndpoints(endpoints =>
261265
{
262-
options.Filters.AddService<RequireLoginFilter>();
263-
})
266+
endpoints.MapRazorPages();
267+
});
264268
```
265-
1. Register the filter in DI in the `ConfigureServices` method in `Startup.cs`
266-
267-
```csharp
268-
services.AddTransient<RequireLoginFilter>();
269-
```
270269
1. Update the `Welcome.cshtml.cs` class with the attribute to ensure it is skipped when the global filter runs:
271270

272271
```csharp
@@ -345,9 +344,9 @@ dotnet aspnet-codegenerator identity --dbContext FrontEnd.Data.IdentityDbContext
345344
return new List<SessionResponse>();
346345
}
347346

348-
var sessionIds = attendee.Sessions.Select(s => s.ID);
347+
var sessionIds = attendee.Sessions.Select(s => s.Id);
349348

350-
sessions.RemoveAll(s => !sessionIds.Contains(s.ID));
349+
sessions.RemoveAll(s => !sessionIds.Contains(s.Id));
351350

352351
return sessions;
353352
}
@@ -364,15 +363,15 @@ dotnet aspnet-codegenerator identity --dbContext FrontEnd.Data.IdentityDbContext
364363
```csharp
365364
var sessions = await _apiClient.GetSessionsByAttendeeAsync(User.Identity.Name);
366365

367-
IsInPersonalAgenda = sessions.Any(s => s.ID == id);
366+
IsInPersonalAgenda = sessions.Any(s => s.Id == id);
368367
```
369368
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:
370369

371370
```html
372371
<form method="post">
373-
<input type="hidden" name="sessionId" value="@Model.Session.ID" />
372+
<input type="hidden" name="sessionId" value="@Model.Session.Id" />
374373
<p>
375-
<a authz-policy="Admin" asp-page="/Admin/EditSession" asp-route-id="@Model.Session.ID" class="btn btn-default btn-sm">Edit</a>
374+
<a authz-policy="Admin" asp-page="/Admin/EditSession" asp-route-id="@Model.Session.Id" class="btn btn-default btn-sm">Edit</a>
376375
@if (Model.IsInPersonalAgenda)
377376
{
378377
<button authz="true" type="submit" asp-page-handler="Remove" class="btn btn-default btn-sm" title="Remove from my personal agenda">
@@ -526,14 +525,14 @@ dotnet aspnet-codegenerator identity --dbContext FrontEnd.Data.IdentityDbContext
526525
@foreach (var speaker in session.Speakers)
527526
{
528527
<li class="list-inline-item">
529-
<a asp-page="Speaker" asp-route-id="@speaker.ID">@speaker.Name</a>
528+
<a asp-page="Speaker" asp-route-id="@speaker.Id">@speaker.Name</a>
530529
</li>
531530
}
532531
</ul>
533532
<form authz="true" method="post">
534-
<input type="hidden" name="sessionId" value="@session.ID" />
533+
<input type="hidden" name="sessionId" value="@session.Id" />
535534
<p class="mb-0">
536-
<a authz-policy="Admin" asp-page="/Admin/EditSession" asp-route-id="@session.ID" class="btn btn-default btn-sm">Edit</a>
535+
<a authz-policy="Admin" asp-page="/Admin/EditSession" asp-route-id="@session.Id" class="btn btn-default btn-sm">Edit</a>
537536
@if (Model.UserSessions.Contains(session.ID))
538537
{
539538
<button type="submit" asp-page-handler="Remove" class="btn btn-default btn-sm bg-transparent" title="Remove from my personal agenda">
@@ -605,7 +604,7 @@ dotnet aspnet-codegenerator identity --dbContext FrontEnd.Data.IdentityDbContext
605604
CurrentDayOffset = day;
606605

607606
var userSessions = await _apiClient.GetSessionsByAttendeeAsync(User.Identity.Name);
608-
UserSessions = userSessions.Select(u => u.ID).ToList();
607+
UserSessions = userSessions.Select(u => u.Id).ToList();
609608

610609
var sessions = await GetSessionsAsync();
611610
//...

0 commit comments

Comments
 (0)