Skip to content

Commit eb5d992

Browse files
Bind user Id to custom type
Bind the user's Id to a custom type, rather than extract it out each time it is needed.
1 parent ef5664c commit eb5d992

File tree

1 file changed

+27
-11
lines changed

1 file changed

+27
-11
lines changed

src/TodoApp/ApiEndpoints.cs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright (c) Martin Costello, 2021. All rights reserved.
22
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.
33

4-
using System.Security.Claims;
54
using Microsoft.AspNetCore.Http.HttpResults;
65
using Microsoft.EntityFrameworkCore;
76
using NodaTime;
@@ -69,20 +68,20 @@ public static IEndpointRouteBuilder MapTodoApiRoutes(this IEndpointRouteBuilder
6968
// Get all Todo items
7069
group.MapGet("/", async (
7170
ITodoService service,
72-
ClaimsPrincipal user,
71+
TodoUser user,
7372
CancellationToken cancellationToken) =>
7473
{
75-
return await service.GetListAsync(user.GetUserId(), cancellationToken);
74+
return await service.GetListAsync(user, cancellationToken);
7675
});
7776

7877
// Get a specific Todo item
7978
group.MapGet("/{id}", async Task<Results<Ok<TodoItemModel>, ProblemHttpResult>> (
8079
Guid id,
81-
ClaimsPrincipal user,
80+
TodoUser user,
8281
ITodoService service,
8382
CancellationToken cancellationToken) =>
8483
{
85-
var model = await service.GetAsync(user.GetUserId(), id, cancellationToken);
84+
var model = await service.GetAsync(user, id, cancellationToken);
8685
return model switch
8786
{
8887
null => TypedResults.Problem("Item not found.", statusCode: StatusCodes.Status404NotFound),
@@ -94,7 +93,7 @@ public static IEndpointRouteBuilder MapTodoApiRoutes(this IEndpointRouteBuilder
9493
// Create a new Todo item
9594
group.MapPost("/", async Task<Results<Created<CreatedTodoItemModel>, ProblemHttpResult>> (
9695
CreateTodoItemModel model,
97-
ClaimsPrincipal user,
96+
TodoUser user,
9897
ITodoService service,
9998
CancellationToken cancellationToken) =>
10099
{
@@ -103,7 +102,7 @@ public static IEndpointRouteBuilder MapTodoApiRoutes(this IEndpointRouteBuilder
103102
return TypedResults.Problem("No item text specified.", statusCode: StatusCodes.Status400BadRequest);
104103
}
105104

106-
var id = await service.AddItemAsync(user.GetUserId(), model.Text, cancellationToken);
105+
var id = await service.AddItemAsync(user, model.Text, cancellationToken);
107106

108107
return TypedResults.Created($"/api/items/{id}", new CreatedTodoItemModel() { Id = id });
109108
})
@@ -112,11 +111,11 @@ public static IEndpointRouteBuilder MapTodoApiRoutes(this IEndpointRouteBuilder
112111
// Mark a Todo item as completed
113112
group.MapPost("/{id}/complete", async Task<Results<NoContent, ProblemHttpResult>> (
114113
Guid id,
115-
ClaimsPrincipal user,
114+
TodoUser user,
116115
ITodoService service,
117116
CancellationToken cancellationToken) =>
118117
{
119-
var wasCompleted = await service.CompleteItemAsync(user.GetUserId(), id, cancellationToken);
118+
var wasCompleted = await service.CompleteItemAsync(user, id, cancellationToken);
120119

121120
return wasCompleted switch
122121
{
@@ -131,11 +130,11 @@ public static IEndpointRouteBuilder MapTodoApiRoutes(this IEndpointRouteBuilder
131130
// Delete a Todo item
132131
group.MapDelete("/{id}", async Task<Results<NoContent, ProblemHttpResult>> (
133132
Guid id,
134-
ClaimsPrincipal user,
133+
TodoUser user,
135134
ITodoService service,
136135
CancellationToken cancellationToken) =>
137136
{
138-
var wasDeleted = await service.DeleteItemAsync(user.GetUserId(), id, cancellationToken);
137+
var wasDeleted = await service.DeleteItemAsync(user, id, cancellationToken);
139138
return wasDeleted switch
140139
{
141140
true => TypedResults.NoContent(),
@@ -152,4 +151,21 @@ public static IEndpointRouteBuilder MapTodoApiRoutes(this IEndpointRouteBuilder
152151

153152
return builder;
154153
}
154+
155+
private readonly struct TodoUser
156+
{
157+
private TodoUser(string id)
158+
{
159+
Id = id;
160+
}
161+
162+
public string Id { get; }
163+
164+
public static implicit operator string(TodoUser value) => value.Id;
165+
166+
public static ValueTask<TodoUser> BindAsync(HttpContext context)
167+
{
168+
return ValueTask.FromResult(new TodoUser(context.User.GetUserId()));
169+
}
170+
}
155171
}

0 commit comments

Comments
 (0)