Skip to content

Commit 7a6312d

Browse files
authored
PetSite updates (#350)
* useId in querystring, userId in trace context, and new layout + more * Basecontroller changes to avoid dual redirect * Change SSM approach * Change SSM Access and change petitem layout slightly * Comment cuteness rate for testing * TryParse check * Comment Food stuff * Aggressive logging for debugging purposes * Add app wide error page * Adding logging to AdoptionController * Add DataProtection dependency for TempData * Make TempData use Session * Get rid of TempData altogether * Logging for ViewData checks * Change from HttpSession Cookies for Payment * Moved userId management to ViewData and hidden controls * Validate querystring in URLs, use inline input fields for userIds * Add Helpers * App wide Error page
1 parent 3985a67 commit 7a6312d

File tree

17 files changed

+222
-141
lines changed

17 files changed

+222
-141
lines changed

PetAdoptions/petsite/petsite/Controllers/AdoptionController.cs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,18 @@ public IActionResult Index([FromQuery] Pet pet)
3333
{
3434
if (EnsureUserId()) return new EmptyResult(); // Redirect happened, stop processing
3535

36-
// Check if pet data exists in TempData (from TakeMeHome redirect)
37-
if (TempData["SelectedPet"] != null)
38-
{
39-
var petJson = TempData["SelectedPet"].ToString();
40-
pet = JsonSerializer.Deserialize<Pet>(petJson);
41-
}
42-
43-
_logger.LogInformation($"In Index Adoption/Index method and about to render the View with: {TempData["SelectedPet"]}");
36+
_logger.LogInformation($"In Index Adoption/Index method with pet: {JsonSerializer.Serialize(pet)}");
4437

4538
return View(pet);
4639
}
4740

4841

4942

5043
[HttpPost]
51-
public async Task<IActionResult> TakeMeHome([FromForm] SearchParams searchParams)
44+
public async Task<IActionResult> TakeMeHome([FromForm] SearchParams searchParams, string userId)
5245
{
53-
EnsureUserId();
46+
if(string.IsNullOrEmpty(userId)) EnsureUserId();
47+
5448
// Add custom span attributes using Activity API
5549
var currentActivity = Activity.Current;
5650
if (currentActivity != null)
@@ -76,7 +70,7 @@ public async Task<IActionResult> TakeMeHome([FromForm] SearchParams searchParams
7670
activity.SetTag("pet.color", searchParams.petcolor);
7771
}
7872
_logger.LogInformation($"Inside Adoption/TakeMeHome with - pettype: {searchParams.pettype}, petcolor: {searchParams.petcolor}, petid: {searchParams.petid}");
79-
pets = await _petSearchService.GetPetDetails(searchParams.pettype, searchParams.petcolor, searchParams.petid);
73+
pets = await _petSearchService.GetPetDetails(searchParams.pettype, searchParams.petcolor, searchParams.petid, "userxxx");
8074
}
8175
}
8276
catch (Exception e)
@@ -89,11 +83,18 @@ public async Task<IActionResult> TakeMeHome([FromForm] SearchParams searchParams
8983
var selectedPet = pets.FirstOrDefault();
9084
if (selectedPet != null)
9185
{
92-
TempData["SelectedPet"] = JsonSerializer.Serialize(selectedPet);
86+
return RedirectToAction("Index", new {
87+
userId = userId,
88+
petid = selectedPet.petid,
89+
pettype = selectedPet.pettype,
90+
petcolor = selectedPet.petcolor,
91+
peturl = selectedPet.peturl,
92+
price = selectedPet.price,
93+
cuteness_rate = selectedPet.cuteness_rate
94+
});
9395
}
94-
_logger.LogInformation($"Redirecting to Index page with : {JsonSerializer.Serialize(selectedPet)}");
9596

96-
return RedirectToAction("Index", new { userId = ViewBag.UserId });
97+
return RedirectToAction("Index", new { userId = userId });
9798
}
9899
}
99100
}

PetAdoptions/petsite/petsite/Controllers/BaseController.cs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,38 +22,41 @@ public class BaseController : Controller
2222
protected bool EnsureUserId()
2323
{
2424
string userId = Request.Query["userId"].ToString();
25-
bool needsRedirect = false;
2625

27-
// Get or generate userId
26+
// Generate userId only on Home/Index if not provided
2827
if (string.IsNullOrEmpty(userId))
2928
{
30-
userId = HttpContext.Session.GetString("userId");
31-
if (string.IsNullOrEmpty(userId))
29+
// Only generate on Home/Index, otherwise require userId
30+
if (ControllerContext.ActionDescriptor.ControllerName == "Home" &&
31+
ControllerContext.ActionDescriptor.ActionName == "Index")
3232
{
3333
userId = UserIds[Random.Next(UserIds.Count)];
34+
35+
if (Request.Method == "GET")
36+
{
37+
var queryString = Request.QueryString.HasValue ? Request.QueryString.Value + "&userId=" + userId : "?userId=" + userId;
38+
Response.Redirect(Request.Path + queryString);
39+
return true;
40+
}
41+
}
42+
else
43+
{
44+
// Redirect to Home/Index if userId is missing on other pages
45+
Response.Redirect("/Home/Index");
46+
return true;
3447
}
35-
// Only redirect for GET requests, not POST
36-
needsRedirect = Request.Method == "GET";
3748
}
3849

39-
// Always set session, ViewBag, and OTEL
40-
HttpContext.Session.SetString("userId", userId);
50+
// Set ViewBag and ViewData for all views
4151
ViewBag.UserId = userId;
52+
ViewData["UserId"] = userId;
4253

4354
var currentActivity = Activity.Current;
4455
if (currentActivity != null && !currentActivity.Tags.Any(tag => tag.Key == "userId"))
4556
{
4657
currentActivity.SetTag("userId", userId);
4758
}
4859

49-
// Redirect only for GET requests
50-
if (needsRedirect)
51-
{
52-
var queryString = Request.QueryString.HasValue ? Request.QueryString.Value + "&userId=" + userId : "?userId=" + userId;
53-
Response.Redirect(Request.Path + queryString);
54-
return true;
55-
}
56-
5760
return false;
5861
}
5962
}

PetAdoptions/petsite/petsite/Controllers/FoodServiceController.cs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Microsoft.Extensions.Logging;
99
using Microsoft.AspNetCore.Http;
1010
using PetSite.Models;
11+
using PetSite.Helpers;
1112

1213
namespace PetSite.Controllers
1314
{
@@ -33,9 +34,9 @@ public async Task<IActionResult> GetFoods()
3334
{
3435
using var httpClient = _httpClientFactory.CreateClient();
3536
var foodApiUrl = _configuration["FOOD_API_URL"] ?? "https://api.example.com/foods";
36-
var userId = ViewBag.UserId?.ToString() ?? HttpContext.Session.GetString("userId");
37-
var separator = foodApiUrl.Contains("?") ? "&" : "?";
38-
var response = await httpClient.GetAsync($"{foodApiUrl}{separator}userId={userId}");
37+
var userId = ViewBag.UserId?.ToString();
38+
var url = UrlHelper.BuildUrl(foodApiUrl, ("userId", userId));
39+
var response = await httpClient.GetAsync(url);
3940
response.EnsureSuccessStatusCode();
4041

4142
var jsonContent = await response.Content.ReadAsStringAsync();
@@ -51,28 +52,28 @@ public async Task<IActionResult> GetFoods()
5152
}
5253

5354
[HttpPost]
54-
public async Task<IActionResult> BuyFood(string foodId)
55+
public async Task<IActionResult> BuyFood(string foodId, string userId)
5556
{
5657
if (EnsureUserId()) return new EmptyResult();
5758

5859
try
5960
{
6061
using var httpClient = _httpClientFactory.CreateClient();
6162
var purchaseApiUrl = _configuration["FOOD_PURCHASE_API_URL"] ?? "https://api.example.com/purchase";
62-
var userId = ViewBag.UserId?.ToString() ?? HttpContext.Session.GetString("userId");
63-
var response = await httpClient.PostAsync($"{purchaseApiUrl}?foodId={foodId}&userId={userId}", null);
63+
// var userId = ViewBag.UserId?.ToString();
64+
var url = UrlHelper.BuildUrl(purchaseApiUrl, ("foodId", foodId), ("userId", userId));
65+
var response = await httpClient.PostAsync(url, null);
6466
response.EnsureSuccessStatusCode();
6567

66-
TempData["FoodPurchaseStatus"] = "success";
67-
TempData["PurchasedFoodId"] = foodId;
68+
// Food purchase successful - could add ViewData or redirect with status
6869
}
6970
catch (Exception ex)
7071
{
7172
_logger.LogError(ex, "Error purchasing food");
72-
TempData["FoodPurchaseStatus"] = "error";
73+
// Food purchase failed - could add ViewData or redirect with error
7374
}
7475

75-
return RedirectToAction("Index", "Payment", new { userId = ViewBag.UserId });
76+
return RedirectToAction("Index", "Payment", new { userId = userId });
7677
}
7778
}
7879
}

PetAdoptions/petsite/petsite/Controllers/HomeController.cs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using Microsoft.AspNetCore.Mvc.Rendering;
1313
using Microsoft.Extensions.Configuration;
1414
using Microsoft.AspNetCore.Http;
15+
using PetSite.Helpers;
1516
using Prometheus;
1617

1718
namespace PetSite.Controllers
@@ -78,8 +79,9 @@ public async Task<IActionResult> HouseKeeping()
7879
string cleanupadoptionsurl = _configuration["cleanupadoptionsurl"];
7980

8081
using var httpClient = _httpClientFactory.CreateClient();
81-
var userId = ViewBag.UserId?.ToString() ?? HttpContext.Session.GetString("userId");
82-
await httpClient.PostAsync($"{cleanupadoptionsurl}?userId={userId}", null);
82+
var userId = ViewBag.UserId?.ToString();
83+
var url = UrlHelper.BuildUrl(cleanupadoptionsurl, ("userId", userId));
84+
await httpClient.PostAsync(url, null);
8385

8486
return View();
8587
}
@@ -112,8 +114,9 @@ public async Task<IActionResult> Index(string selectedPetType, string selectedPe
112114
activity.SetTag("pet.color", selectedPetColor);
113115
activity.SetTag("pet.id", petid);
114116
}
115-
116-
Pets = await _petSearchService.GetPetDetails(selectedPetType, selectedPetColor, petid);
117+
118+
var userId = Request.Query["userId"].ToString();
119+
Pets = await _petSearchService.GetPetDetails(selectedPetType, selectedPetColor, petid, userId);
117120
}
118121
}
119122
catch (HttpRequestException e)
@@ -159,8 +162,16 @@ public async Task<IActionResult> Index(string selectedPetType, string selectedPe
159162
}
160163

161164
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
162-
public IActionResult Error()
165+
public IActionResult Error(string userId, string message)
163166
{
167+
if (!string.IsNullOrEmpty(userId))
168+
{
169+
ViewBag.UserId = userId;
170+
ViewData["UserId"] = userId;
171+
}
172+
173+
ViewBag.ErrorMessage = message;
174+
164175
return View(new ErrorViewModel {RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier});
165176
}
166177
}

PetAdoptions/petsite/petsite/Controllers/PaymentController.cs

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
using Amazon.SQS;
88
using Microsoft.Extensions.Configuration;
99
using Microsoft.AspNetCore.Http;
10+
using PetSite.Helpers;
1011
using Prometheus;
1112

1213
namespace PetSite.Controllers
1314
{
1415
public class PaymentController : BaseController
1516
{
1617
private static string _txStatus = String.Empty;
17-
18+
1819
private readonly ILogger<PaymentController> _logger;
1920

2021
private readonly IHttpClientFactory _httpClientFactory;
@@ -24,7 +25,8 @@ public class PaymentController : BaseController
2425
private static readonly Counter PetAdoptionCount =
2526
Metrics.CreateCounter("petsite_petadoptions_total", "Count the number of Pets adopted");
2627

27-
public PaymentController(ILogger<PaymentController> logger, IConfiguration configuration, IHttpClientFactory httpClientFactory)
28+
public PaymentController(ILogger<PaymentController> logger, IConfiguration configuration,
29+
IHttpClientFactory httpClientFactory)
2830
{
2931
_configuration = configuration;
3032
_httpClientFactory = httpClientFactory;
@@ -33,40 +35,39 @@ public PaymentController(ILogger<PaymentController> logger, IConfiguration confi
3335

3436
// GET: Payment
3537
[HttpGet]
36-
public ActionResult Index()
38+
public ActionResult Index([FromQuery] string userId, string status)
3739
{
3840
if (EnsureUserId()) return new EmptyResult();
3941

40-
// Transfer TempData to ViewData for the view
41-
if (TempData["txStatus"] != null)
42-
{
43-
ViewData["txStatus"] = TempData["txStatus"];
44-
ViewData["error"] = TempData["error"];
45-
}
46-
47-
// Handle food purchase status
48-
if (TempData["FoodPurchaseStatus"] != null)
49-
{
50-
ViewData["FoodPurchaseStatus"] = TempData["FoodPurchaseStatus"];
51-
ViewData["PurchasedFoodId"] = TempData["PurchasedFoodId"];
52-
}
42+
// Transfer Session to ViewData for the view
43+
ViewData["txStatus"] = status;
5344

45+
// ViewData["FoodPurchaseStatus"] = HttpContext.Session.GetString("FoodPurchaseStatus");
46+
// ViewData["PurchasedFoodId"] = HttpContext.Session.GetString("PurchasedFoodId");
47+
//
48+
// Clear session data after reading
49+
// HttpContext.Session.Remove("FoodPurchaseStatus");
50+
// HttpContext.Session.Remove("PurchasedFoodId");
51+
//
5452
return View();
5553
}
5654

5755
// POST: Payment/MakePayment
5856
[HttpPost]
5957
// [ValidateAntiForgeryToken]
60-
public async Task<IActionResult> MakePayment(string petId, string pettype)
58+
public async Task<IActionResult> MakePayment(string petId, string pettype, string userId)
6159
{
62-
if (EnsureUserId()) return new EmptyResult();
60+
//if (EnsureUserId()) return new EmptyResult();
61+
62+
if (string.IsNullOrEmpty(userId)) EnsureUserId();
63+
6364
// Add custom span attributes using Activity API
6465
var currentActivity = Activity.Current;
6566
if (currentActivity != null)
6667
{
6768
currentActivity.SetTag("pet.id", petId);
6869
currentActivity.SetTag("pet.type", pettype);
69-
70+
7071
_logger.LogInformation($"Inside MakePayment Action method - PetId:{petId} - PetType:{pettype}");
7172
}
7273

@@ -80,29 +81,27 @@ public async Task<IActionResult> MakePayment(string petId, string pettype)
8081
activity.SetTag("pet.id", petId);
8182
activity.SetTag("pet.type", pettype);
8283
}
83-
var userId = ViewBag.UserId?.ToString() ?? HttpContext.Session.GetString("userId");
84+
85+
// userId parameter is already available
8486

8587
using var httpClient = _httpClientFactory.CreateClient();
8688

87-
await httpClient.PostAsync($"{_configuration["paymentapiurl"]}?petId={petId}&petType={pettype}&userId={userId}",
88-
null);
89+
var url = UrlHelper.BuildUrl(_configuration["paymentapiurl"],
90+
("petId", petId), ("petType", pettype), ("userId", userId));
91+
await httpClient.PostAsync(url, null);
8992
}
9093

9194
//Increase purchase metric count
9295
PetAdoptionCount.Inc();
93-
TempData["txStatus"] = "success";
94-
return RedirectToAction("Index", new { userId = ViewBag.UserId });
96+
return RedirectToAction("Index", new { userId = userId, status = "success" });
9597
}
9698
catch (Exception ex)
9799
{
98-
TempData["txStatus"] = "failure";
99-
TempData["error"] = ex.Message;
100-
101100
// Log the exception
102101
_logger.LogError(ex, $"Error in MakePayment: {ex.Message}");
103-
104-
return RedirectToAction("Index", new { userId = ViewBag.UserId });
102+
103+
return RedirectToAction("Index", new { userId = userId, status = ex.Message });
105104
}
106105
}
107106
}
108-
}
107+
}

PetAdoptions/petsite/petsite/Controllers/PetHistoryController.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Diagnostics;
77
using Microsoft.Extensions.Logging;
88
using Microsoft.AspNetCore.Http;
9+
using PetSite.Helpers;
910

1011
namespace PetSite.Controllers;
1112

@@ -45,8 +46,9 @@ public async Task<IActionResult> Index()
4546
using (var activity = Activity.Current?.Source?.StartActivity("Calling GetPetAdoptionsHistory API"))
4647
{
4748
using var httpClient = _httpClientFactory.CreateClient();
48-
var userId = HttpContext.Session.GetString("userId") ?? "unknown";
49-
ViewData["pethistory"] = await httpClient.GetStringAsync($"{_pethistoryurl}/api/home/transactions?userId={userId}");
49+
var userId = ViewBag.UserId?.ToString() ?? "unknown";
50+
var url = UrlHelper.BuildUrl($"{_pethistoryurl}/api/home/transactions", ("userId", userId));
51+
ViewData["pethistory"] = await httpClient.GetStringAsync(url);
5052
}
5153
}
5254
catch (Exception e)
@@ -79,8 +81,9 @@ public async Task<IActionResult> DeletePetAdoptionsHistory()
7981
using (var activity = Activity.Current?.Source?.StartActivity("Calling DeletePetAdoptionsHistory API"))
8082
{
8183
using var httpClient = _httpClientFactory.CreateClient();
82-
var userId = HttpContext.Session.GetString("userId") ?? "unknown";
83-
ViewData["pethistory"] = await httpClient.DeleteAsync($"{_pethistoryurl}/api/home/transactions?userId={userId}");
84+
var userId = ViewBag.UserId?.ToString() ?? "unknown";
85+
var url = UrlHelper.BuildUrl($"{_pethistoryurl}/api/home/transactions", ("userId", userId));
86+
ViewData["pethistory"] = await httpClient.DeleteAsync(url);
8487
}
8588
}
8689
catch (Exception e)

0 commit comments

Comments
 (0)