-
@User.Identity.Name
+
@User?.Identity?.Name
diff --git a/save-points/03-show-order-status/BlazingPizza.Server/BlazingPizza.Server.csproj b/save-points/03-show-order-status/BlazingPizza.Server/BlazingPizza.Server.csproj
index 227890e1..a1043cb6 100644
--- a/save-points/03-show-order-status/BlazingPizza.Server/BlazingPizza.Server.csproj
+++ b/save-points/03-show-order-status/BlazingPizza.Server/BlazingPizza.Server.csproj
@@ -3,6 +3,7 @@
$(TargetFrameworkVersion)
true
+ enable
diff --git a/save-points/03-show-order-status/BlazingPizza.Server/OrdersController.cs b/save-points/03-show-order-status/BlazingPizza.Server/OrdersController.cs
index 37e37cc5..a0a99b09 100644
--- a/save-points/03-show-order-status/BlazingPizza.Server/OrdersController.cs
+++ b/save-points/03-show-order-status/BlazingPizza.Server/OrdersController.cs
@@ -61,12 +61,12 @@ public async Task> PlaceOrder(Order order)
// new specials and toppings
foreach (var pizza in order.Pizzas)
{
- pizza.SpecialId = pizza.Special.Id;
+ pizza.SpecialId = pizza.Special?.Id ?? 0;
pizza.Special = null;
foreach (var topping in pizza.Toppings)
{
- topping.ToppingId = topping.Topping.Id;
+ topping.ToppingId = topping.Topping?.Id ?? 0;
topping.Topping = null;
}
}
@@ -75,7 +75,7 @@ public async Task> PlaceOrder(Order order)
await _db.SaveChangesAsync();
// In the background, send push notifications if possible
- var subscription = await _db.NotificationSubscriptions.Where(e => e.UserId == GetUserId()).SingleOrDefaultAsync();
+ var subscription = await _db.NotificationSubscriptions.Where(e => e.UserId == PizzaApiExtensions.GetUserId(HttpContext)).SingleOrDefaultAsync();
if (subscription != null)
{
_ = TrackAndSendNotificationsAsync(order, subscription);
@@ -84,11 +84,6 @@ public async Task> PlaceOrder(Order order)
return order.OrderId;
}
- private string GetUserId()
- {
- return HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
- }
-
private static async Task TrackAndSendNotificationsAsync(Order order, NotificationSubscription subscription)
{
// In a realistic case, some other backend process would track
diff --git a/save-points/03-show-order-status/BlazingPizza.Server/PizzaApiExtensions.cs b/save-points/03-show-order-status/BlazingPizza.Server/PizzaApiExtensions.cs
index 524ca759..e82b077b 100644
--- a/save-points/03-show-order-status/BlazingPizza.Server/PizzaApiExtensions.cs
+++ b/save-points/03-show-order-status/BlazingPizza.Server/PizzaApiExtensions.cs
@@ -49,9 +49,11 @@ public static WebApplication MapPizzaApi(this WebApplication app)
}
- private static string GetUserId(HttpContext context)
+ public static string GetUserId(HttpContext context)
{
- return context.User.FindFirstValue(ClaimTypes.NameIdentifier);
+ string? result = context.User.FindFirstValue(ClaimTypes.NameIdentifier);
+ if (result is null) throw new UnauthorizedAccessException("User claim was not found.");
+ return result;
}
}
\ No newline at end of file
diff --git a/save-points/03-show-order-status/BlazingPizza.Server/PizzaStoreContext.cs b/save-points/03-show-order-status/BlazingPizza.Server/PizzaStoreContext.cs
index 50ac87e4..1505c7af 100644
--- a/save-points/03-show-order-status/BlazingPizza.Server/PizzaStoreContext.cs
+++ b/save-points/03-show-order-status/BlazingPizza.Server/PizzaStoreContext.cs
@@ -35,4 +35,4 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
// Inline the Lat-Long pairs in Order rather than having a FK to another table
modelBuilder.Entity().OwnsOne(o => o.DeliveryLocation);
}
-}
+}
\ No newline at end of file
diff --git a/save-points/03-show-order-status/BlazingPizza.Server/Startup.cs b/save-points/03-show-order-status/BlazingPizza.Server/Startup.cs
new file mode 100644
index 00000000..4a35b695
--- /dev/null
+++ b/save-points/03-show-order-status/BlazingPizza.Server/Startup.cs
@@ -0,0 +1,69 @@
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+
+namespace BlazingPizza.Server
+{
+ public class Startup
+ {
+ public Startup(IConfiguration configuration)
+ {
+ Configuration = configuration;
+ }
+
+ public IConfiguration Configuration { get; }
+
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddControllersWithViews();
+ services.AddRazorPages();
+
+ services.AddDbContext(options =>
+ options.UseSqlite("Data Source=pizza.db"));
+
+ services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true)
+ .AddEntityFrameworkStores();
+
+ services.AddIdentityServer()
+ .AddApiAuthorization();
+
+ services.AddAuthentication()
+ .AddIdentityServerJwt();
+ }
+
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+ {
+ if (env.IsDevelopment())
+ {
+ app.UseDeveloperExceptionPage();
+ app.UseWebAssemblyDebugging();
+ }
+ else
+ {
+ app.UseExceptionHandler("/Error");
+ // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
+ app.UseHsts();
+ }
+
+ app.UseHttpsRedirection();
+ app.UseBlazorFrameworkFiles();
+ app.UseStaticFiles();
+
+ app.UseRouting();
+
+ app.UseAuthentication();
+ app.UseIdentityServer();
+ app.UseAuthorization();
+
+ app.UseEndpoints(endpoints => {
+ endpoints.MapControllers();
+ endpoints.MapRazorPages();
+ endpoints.MapFallbackToFile("index.html");
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/save-points/03-show-order-status/BlazingPizza.Shared/Address.cs b/save-points/03-show-order-status/BlazingPizza.Shared/Address.cs
index f2d1daa4..d1a53375 100644
--- a/save-points/03-show-order-status/BlazingPizza.Shared/Address.cs
+++ b/save-points/03-show-order-status/BlazingPizza.Shared/Address.cs
@@ -1,20 +1,18 @@
-using System.ComponentModel.DataAnnotations;
-
-namespace BlazingPizza;
+namespace BlazingPizza;
public class Address
{
public int Id { get; set; }
- public string Name { get; set; }
+ public string Name { get; set; } = string.Empty;
- public string Line1 { get; set; }
+ public string Line1 { get; set; } = string.Empty;
- public string Line2 { get; set; }
+ public string Line2 { get; set; } = string.Empty;
- public string City { get; set; }
+ public string City { get; set; } = string.Empty;
- public string Region { get; set; }
+ public string Region { get; set; } = string.Empty;
- public string PostalCode { get; set; }
+ public string PostalCode { get; set; } = string.Empty;
}
diff --git a/save-points/03-show-order-status/BlazingPizza.Shared/BlazingPizza.Shared.csproj b/save-points/03-show-order-status/BlazingPizza.Shared/BlazingPizza.Shared.csproj
index 075ddd60..785c204e 100644
--- a/save-points/03-show-order-status/BlazingPizza.Shared/BlazingPizza.Shared.csproj
+++ b/save-points/03-show-order-status/BlazingPizza.Shared/BlazingPizza.Shared.csproj
@@ -1,13 +1,18 @@
-
- $(TargetFrameworkVersion)
- BlazingPizza
+
+ $(TargetFrameworkVersion)
+ BlazingPizza
true
-
+ enable
+
-
-
-
+
+
+
+
+
+
+
diff --git a/save-points/03-show-order-status/BlazingPizza.Shared/NotificationSubscription.cs b/save-points/03-show-order-status/BlazingPizza.Shared/NotificationSubscription.cs
index 5c99e3f4..16711e31 100644
--- a/save-points/03-show-order-status/BlazingPizza.Shared/NotificationSubscription.cs
+++ b/save-points/03-show-order-status/BlazingPizza.Shared/NotificationSubscription.cs
@@ -2,13 +2,13 @@
public class NotificationSubscription
{
- public int NotificationSubscriptionId { get; set; }
+ public required int NotificationSubscriptionId { get; set; }
- public string UserId { get; set; }
+ public required string UserId { get; set; }
- public string Url { get; set; }
+ public required string Url { get; set; }
- public string P256dh { get; set; }
+ public required string P256dh { get; set; }
- public string Auth { get; set; }
+ public required string Auth { get; set; }
}
diff --git a/save-points/03-show-order-status/BlazingPizza.Shared/Order.cs b/save-points/03-show-order-status/BlazingPizza.Shared/Order.cs
index 180ec55b..f1211588 100644
--- a/save-points/03-show-order-status/BlazingPizza.Shared/Order.cs
+++ b/save-points/03-show-order-status/BlazingPizza.Shared/Order.cs
@@ -6,13 +6,15 @@ public class Order
{
public int OrderId { get; set; }
- public string UserId { get; set; }
+ // Set by the server during POST
+ public string? UserId { get; set; }
public DateTime CreatedTime { get; set; }
public Address DeliveryAddress { get; set; } = new Address();
- public LatLong DeliveryLocation { get; set; }
+ // Set by server during POST
+ public LatLong? DeliveryLocation { get; set; }
public List Pizzas { get; set; } = new List();
diff --git a/save-points/03-show-order-status/BlazingPizza.Shared/OrderWithStatus.cs b/save-points/03-show-order-status/BlazingPizza.Shared/OrderWithStatus.cs
index fbfac7af..c0e3495a 100644
--- a/save-points/03-show-order-status/BlazingPizza.Shared/OrderWithStatus.cs
+++ b/save-points/03-show-order-status/BlazingPizza.Shared/OrderWithStatus.cs
@@ -9,16 +9,19 @@ public class OrderWithStatus
public readonly static TimeSpan PreparationDuration = TimeSpan.FromSeconds(10);
public readonly static TimeSpan DeliveryDuration = TimeSpan.FromMinutes(1); // Unrealistic, but more interesting to watch
- public Order Order { get; set; }
+ // Set from DB
+ public Order Order { get; set; } = null!;
- public string StatusText { get; set; }
+ // Set from Order
+ public string StatusText { get; set; } = null!;
public bool IsDelivered => StatusText == "Delivered";
- public List MapMarkers { get; set; }
+ public List MapMarkers { get; set; } = null!;
public static OrderWithStatus FromOrder(Order order)
{
+ ArgumentNullException.ThrowIfNull(order.DeliveryLocation);
// To simulate a real backend process, we fake status updates based on the amount
// of time since the order was placed
string statusText;
@@ -65,6 +68,7 @@ public static OrderWithStatus FromOrder(Order order)
private static LatLong ComputeStartPosition(Order order)
{
+ ArgumentNullException.ThrowIfNull(order.DeliveryLocation);
// Random but deterministic based on order ID
var rng = new Random(order.OrderId);
var distance = 0.01 + rng.NextDouble() * 0.02;
diff --git a/save-points/03-show-order-status/BlazingPizza.Shared/Pizza.cs b/save-points/03-show-order-status/BlazingPizza.Shared/Pizza.cs
index 2a7a1c29..150de954 100644
--- a/save-points/03-show-order-status/BlazingPizza.Shared/Pizza.cs
+++ b/save-points/03-show-order-status/BlazingPizza.Shared/Pizza.cs
@@ -15,22 +15,24 @@ public class Pizza
public int OrderId { get; set; }
- public PizzaSpecial Special { get; set; }
+ public PizzaSpecial? Special { get; set; }
public int SpecialId { get; set; }
public int Size { get; set; }
- public List Toppings { get; set; }
+ public List Toppings { get; set; } = new();
public decimal GetBasePrice()
{
+ if(Special == null) throw new NullReferenceException($"{nameof(Special)} was null when calculating Base Price.");
return ((decimal)Size / (decimal)DefaultSize) * Special.BasePrice;
}
public decimal GetTotalPrice()
{
- return GetBasePrice() + Toppings.Sum(t => t.Topping.Price);
+ if (Toppings.Any(t => t.Topping is null)) throw new NullReferenceException($"{nameof(Toppings)} contained null when calculating the Total Price.");
+ return GetBasePrice() + Toppings.Sum(t => t.Topping!.Price);
}
public string GetFormattedTotalPrice()
diff --git a/save-points/03-show-order-status/BlazingPizza.Shared/PizzaSpecial.cs b/save-points/03-show-order-status/BlazingPizza.Shared/PizzaSpecial.cs
index 1fd9006a..d53ab286 100644
--- a/save-points/03-show-order-status/BlazingPizza.Shared/PizzaSpecial.cs
+++ b/save-points/03-show-order-status/BlazingPizza.Shared/PizzaSpecial.cs
@@ -7,13 +7,13 @@ public class PizzaSpecial
{
public int Id { get; set; }
- public string Name { get; set; }
+ public string Name { get; set; } = string.Empty;
public decimal BasePrice { get; set; }
- public string Description { get; set; }
+ public string Description { get; set; } = string.Empty;
- public string ImageUrl { get; set; }
+ public string ImageUrl { get; set; } = "img/pizzas/cheese.jpg";
public string GetFormattedBasePrice() => BasePrice.ToString("0.00");
}
\ No newline at end of file
diff --git a/save-points/03-show-order-status/BlazingPizza.Shared/PizzaTopping.cs b/save-points/03-show-order-status/BlazingPizza.Shared/PizzaTopping.cs
index 1c062732..724f1c06 100644
--- a/save-points/03-show-order-status/BlazingPizza.Shared/PizzaTopping.cs
+++ b/save-points/03-show-order-status/BlazingPizza.Shared/PizzaTopping.cs
@@ -2,7 +2,7 @@
public class PizzaTopping
{
- public Topping Topping { get; set; }
+ public Topping? Topping { get; set; }
public int ToppingId { get; set; }
diff --git a/save-points/03-show-order-status/BlazingPizza.Shared/Topping.cs b/save-points/03-show-order-status/BlazingPizza.Shared/Topping.cs
index 4eb67ae9..29b9e790 100644
--- a/save-points/03-show-order-status/BlazingPizza.Shared/Topping.cs
+++ b/save-points/03-show-order-status/BlazingPizza.Shared/Topping.cs
@@ -4,7 +4,7 @@ public class Topping
{
public int Id { get; set; }
- public string Name { get; set; }
+ public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
diff --git a/save-points/03-show-order-status/BlazingPizza.Shared/UserInfo.cs b/save-points/03-show-order-status/BlazingPizza.Shared/UserInfo.cs
index babb4315..fb0045bf 100644
--- a/save-points/03-show-order-status/BlazingPizza.Shared/UserInfo.cs
+++ b/save-points/03-show-order-status/BlazingPizza.Shared/UserInfo.cs
@@ -4,6 +4,6 @@ public class UserInfo
{
public bool IsAuthenticated { get; set; }
- public string Name { get; set; }
+ public string Name { get; set; } = string.Empty;
}
\ No newline at end of file