Skip to content

Commit

Permalink
Add improvement item for page 369
Browse files Browse the repository at this point in the history
  • Loading branch information
markjprice committed Jul 26, 2023
1 parent f827a14 commit 5ebd516
Show file tree
Hide file tree
Showing 14 changed files with 912 additions and 2 deletions.
2 changes: 1 addition & 1 deletion docs/errata/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ If you find any mistakes in the seventh edition, *C# 11 and .NET 7 - Modern Cros

[**Errata** (47 items)](errata.md): Typos, tool user interface changes, or mistakes in code that would cause a compilation error that prevents a successful build.

[**Improvements** (42 items)](improvements.md): Changes to text or code that would improve the content. These are optional.
[**Improvements** (43 items)](improvements.md): Changes to text or code that would improve the content. These are optional.

[**Common Errors** (6 items)](common-errors.md): These are some of the most common errors that a reader might encounter when trying to get code in book tasks to work, or when trying to write your own code.

Expand Down
14 changes: 13 additions & 1 deletion docs/errata/improvements.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
**Improvements** (42 items)
**Improvements** (43 items)

If you have suggestions for improvements, then please [raise an issue in this repository](https://github.com/markjprice/cs11dotnet7/issues) or email me at markjprice (at) gmail.com.

Expand Down Expand Up @@ -28,6 +28,7 @@ If you have suggestions for improvements, then please [raise an issue in this re
- [Page 339 - Viewing source links with Visual Studio 2022](#page-339---viewing-source-links-with-visual-studio-2022)
- [Page 343 - Packaging a library for NuGet](#page-343---packaging-a-library-for-nuget)
- [Page 351 - Using non-.NET Standard libraries](#page-351---using-non-net-standard-libraries)
- [Page 369 - Activating regular expression syntax coloring](#page-369---activating-regular-expression-syntax-coloring)
- [Page 378 - Dictionaries](#page-378---dictionaries)
- [Page 444 - Connecting to a database](#page-444---connecting-to-a-database)
- [Page 453 - Scaffolding models using an existing database](#page-453---scaffolding-models-using-an-existing-database)
Expand Down Expand Up @@ -706,6 +707,17 @@ for (int i = 0; i < matrix.Axes[1].Points.Length; i++)
}
```

# Page 369 - Activating regular expression syntax coloring

In Step 2, I wrote, "Right-click in the `StringSyntax` attribute, select **Go To Implementation**, and note..."

Visual Studio 2022 has two similar features:

- **Go To Definition** *F12*: Should go to the decompiled metadata for a member or type. But if you have previously viewed source link, then it goes to source link!
- **Go To Implementation** *Ctrl* + *F12*: Should go to the source link implementation for a member or type. But if you have disabled source link, then it goes to the decompiled metadata.

In the next edition, I will add a note about this.

# Page 378 - Dictionaries

In the next edition, I will add a note at the bottom of this section to set an expectation that readers will come across dictionaries again later in the book in more practical ways.
Expand Down
32 changes: 32 additions & 0 deletions vs4win/PracticalApps/Northwind.Web/Pages/CustomerOrders.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@page
@using Northwind.Web.Pages
@using Packt.Shared
@model CustomerOrdersModel
@{
string title = "Customer and their orders";
ViewData["Title"] = $"Northwind B2B - {title}";
}
<div class="row">
<h1 class="display-2">@title</h1>
<div>
@if (Model.Customer is not null)
{
<div>
<div>@Model.Customer.CompanyName</div>
</div>
<div>
<table>
<thead>
<tr><th>Order Id</th><th>Order Date</th></tr>
</thead>
<tbody>
@foreach (Order o in Model.Customer.Orders)
{
<tr><td>@o.OrderId</td><td>@o.OrderDate</td></tr>
}
</tbody>
</table>
</div>
}
</div>
</div>
25 changes: 25 additions & 0 deletions vs4win/PracticalApps/Northwind.Web/Pages/CustomerOrders.cshtml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Microsoft.AspNetCore.Mvc.RazorPages; // PageModel
using Microsoft.EntityFrameworkCore; // Include extension method
using Packt.Shared; // Customer

namespace Northwind.Web.Pages;

public class CustomerOrdersModel : PageModel
{
public Customer? Customer;

private NorthwindContext db;

public CustomerOrdersModel(NorthwindContext db)
{
this.db = db;
}

public void OnGet()
{
string id = HttpContext.Request.Query["id"];

Customer = db.Customers.Include(c => c.Orders)
.SingleOrDefault(c => c.CustomerId == id);
}
}
40 changes: 40 additions & 0 deletions vs4win/PracticalApps/Northwind.Web/Pages/Customers.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
@page
@using Northwind.Web.Pages
@using Packt.Shared
@model CustomersModel
@{
string title = "Customers by Country";
ViewData["Title"] = $"Northwind B2B - {title}";
}
<div class="row">
<h1 class="display-2">@title</h1>
<div>
<h2>Exercise 14.2 – Practice building a data-driven web page</h2>
</div>
<div class="accordion" id="accordionCustomers">
@if (Model.CustomersByCountry is not null)
{
@foreach (IGrouping<string?, Customer> cbc in Model.CustomersByCountry)
{
<div class="accordion-item">
<h2 class="accordion-header" id="header@(cbc.Key)">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapse@(cbc.Key)" aria-expanded="true" aria-controls="collapse@(cbc.Key)">
@cbc.Key has @cbc.Count() customers
</button>
</h2>
<div id="collapse@(cbc.Key)" class="accordion-collapse collapse" aria-labelledby="heading@(cbc.Key)" data-bs-parent="#accordionCustomers">
<div class="accordion-body">
<ul>
@foreach (Customer c in cbc)
{
<li><a href="[email protected]">
@c.CompanyName</a></li>
}
</ul>
</div>
</div>
</div>
}
}
</div>
</div>
21 changes: 21 additions & 0 deletions vs4win/PracticalApps/Northwind.Web/Pages/Customers.cshtml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Microsoft.AspNetCore.Mvc.RazorPages; // PageModel
using Packt.Shared; // Customer

namespace Northwind.Web.Pages;

public class CustomersModel : PageModel
{
public ILookup<string?, Customer>? CustomersByCountry;

private NorthwindContext db;

public CustomersModel(NorthwindContext db)
{
this.db = db;
}

public void OnGet()
{
CustomersByCountry = db.Customers.ToLookup(c => c.Country);
}
}
190 changes: 190 additions & 0 deletions vs4win/PracticalApps/Northwind.Web/Pages/Functions.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
@page
@using Northwind.Web.Pages
@using Packt.Shared
@model FunctionsModel
@{
string title = "Functions";
ViewData["Title"] = $"Northwind B2B - {title}";

string collapsedTimesTable = Model.TimesTableNumberInput.HasValue ? string.Empty : "collapse";
string collapsedCalculateTax = Model.Amount.HasValue ? string.Empty : "collapse";
string collapsedFactorial = Model.FactorialNumber.HasValue ? string.Empty : "collapse";
string collapsedFibonacci = Model.FibonacciNumber.HasValue ? string.Empty : "collapse";
}
<div class="row">
<h1 class="display-2">@title</h1>
<div>
<h2>Exercise 14.3 – Practice building web pages for console apps</h2>
<div>Provide a web user interface to output times tables, calculate tax, and generate factorials and the Fibonacci sequence.</div>
</div>
<div class="accordion" id="accordionFunctions">
<div class="accordion-item">
<h2 class="accordion-header" id="headerTimesTable">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTimesTable" aria-expanded="true" aria-controls="collapseTimesTable">
Times Table
</button>
</h2>
<div id="collapseTimesTable" class="accordion-collapse @collapsedTimesTable" aria-labelledby="headingTimesTable" data-bs-parent="#accordionTimesTable">
<div class="accordion-body">
<form>
<div class="mb-3">
<label for="timesTableNumberInput" class="form-label">Number</label>
<input type="number" class="form-control" id="timesTableNumberInput" name="timesTableNumberInput" aria-describedby="timesTableNumberHelp">
<div id="timesTableNumberHelp" class="form-text">Enter an integer between 1 and 100.</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
@if (Model.TimesTableNumberInput.HasValue)
{
<div class="card" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">@Model.TimesTableNumberInput times table</h5>
@for (int i = 1; i <= 12; i++)
{
<div>
@i x @Model.TimesTableNumberInput = @(i * Model.TimesTableNumberInput)
</div>
}
</div>

</div>
}
</div>
</div>
</div>

<div class="accordion-item">
<h2 class="accordion-header" id="headerCalculateTax">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseCalculateTax" aria-expanded="true" aria-controls="collapseCalculateTax">
Calculate Tax
</button>
</h2>
<div id="collapseCalculateTax" class="accordion-collapse @collapsedCalculateTax" aria-labelledby="headingCalculateTax" data-bs-parent="#accordionCalculateTax">
<div class="accordion-body">
<form>
<div class="mb-3">
<label for="calculateTaxAmountInput" class="form-label">Amount</label>
<input type="number" class="form-control" id="calculateTaxAmountInput" name="calculateTaxAmountInput" aria-describedby="calculateTaxAmountInputHelp">
<div id="calculateTaxAmountInputHelp" class="form-text">Enter a monetary value.</div>
</div>
<div class="mb-3">
<label for="calculateTaxRegionCodeInput" class="form-label">Region</label>
<select class="form-control" id="calculateTaxRegionCodeInput" name="calculateTaxRegionCodeInput" aria-describedby="calculateTaxRegionCodeInputHelp">
<optgroup label="Europe">
<option value="DK">Denmark</option>
<option value="FR">France</option>
<option value="HU">Hungary</option>
<option value="NO">Norway</option>
<option value="CH">Switzerland</option>
<option value="GB">United Kingdom</option>
</optgroup>
<optgroup label="United States">
<option value="AK">Alaska</option>
<option value="OR">Oregon</option>
<option value="MT">Montana</option>
<option value="ND">North Dakota</option>
<option value="WI">Wisconsin</option>
<option value="ME">Maine</option>
<option value="VA">Virginia</option>
<option value="CA">California</option>
<option value="OT">Other</option>
</optgroup>
</select>
<div id="calculateTaxRegionCodeInputHelp" class="form-text">Select a European or US state.</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
@if (Model.Amount.HasValue)
{
<div class="card" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">You must pay @Model.TaxToPay in tax.</h5>
</div>

</div>
}
</div>
</div>
</div>

<div class="accordion-item">
<h2 class="accordion-header" id="headerFactorials">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseFactorials" aria-expanded="true" aria-controls="collapseFactorials">
Factorials
</button>
</h2>
<div id="collapseFactorials" class="accordion-collapse @collapsedFactorial" aria-labelledby="headingFactorials" data-bs-parent="#accordionFactorials">
<div class="accordion-body">
<div>
<form>
<div class="mb-3">
<label for="factorialNumberInput" class="form-label">Number</label>
<input type="number" class="form-control" id="factorialNumberInput" name="factorialNumberInput" aria-describedby="factorialNumberHelp">
<div id="factorialNumberHelp" class="form-text">Enter an integer between 1 and 12.</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
@if (Model.FactorialNumber.HasValue)
{
<div class="card" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">@(Model.FactorialNumber)!</h5>
<div>
@(Model.FactorialNumber)! = @(Model.FactorialResult is null ? "null" : Model.FactorialResult.Value.ToString("N0"))
</div>
</div>

</div>
}
@if (Model.FactorialException is not null)
{
<div class="card" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">Exception</h5>
<div>
@Model.FactorialException.Message
</div>
</div>

</div>
}
</div>
</div>
</div>
</div>

<div class="accordion-item">
<h2 class="accordion-header" id="headerFibonacciSequence">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseFibonacciSequence" aria-expanded="true" aria-controls="collapseFibonacciSequence">
Fibonacci sequence
</button>
</h2>
<div id="collapseFibonacciSequence" class="accordion-collapse @collapsedFibonacci" aria-labelledby="headingFibonacciSequence" data-bs-parent="#accordionCustomers">
<div class="accordion-body">
<div>
<form>
<div class="mb-3">
<label for="fibonacciNumberInput" class="form-label">Term</label>
<input type="number" class="form-control" id="fibonacciNumberInput" name="fibonacciNumberInput" aria-describedby="fibonacciNumberHelp">
<div id="fibonacciNumberHelp" class="form-text">Enter an integer between 1 and 40.</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
@if (Model.FibonacciNumber.HasValue)
{
<div class="card" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">Fibonacci term @Model.FibonacciNumber</h5>
<div>
Term @Model.FibonacciNumber of the fibonacci sequence = @(Model.FibonacciResult is null ? "null" : Model.FibonacciResult.Value.ToString("N0"))
</div>
</div>

</div>
}
</div>
</div>
</div>
</div>
</div>
</div>
Loading

0 comments on commit 5ebd516

Please sign in to comment.