Blazor Walkthrough: Act I - rochellew/csci_1260_spring2025 GitHub Wiki
🧙 "Greetings, intrepid developer! You have been chosen for a task of the utmost importance. A nameless traveling explorer has documented some of their incredible discoveries in their field guide; creatures and plants possessed of great magical abilities.
Through these hallowed tutorials, I will help you to create a digital application using the fabled Microsoft Blazor framework to catalogue these organisms. Consult these guides as your knowledge grows over the next few weeks, as new tasks will be laid before you.
Best of luck!"
For your first task, we will be performing a simple setup of a blank Blazor application. The steps below will describe what you should do, as well as explain what the various components of a .NET project are.
Before you begin, take some time to familiarize yourself with the information listed below.
- A
.sln
file (the solution file) is used by Visual Studio. Its purpose is to hold several projects together, not unlike a 3-ring binder can hold several writing projects or notes.- You open the
.sln
file when you want to work on the whole application in Visual Studio. - In this walkthrough, your solution will include:
- The Blazor project
- A class library
- You open the
- A
.csproj
file (the C# project file) is essentially a blueprint for a specific project inside the solution. Metadata about the project(s) are located in this file.- Visual Studio can use the
.csproj
file to build the project.- What files to include
- Which NuGet (external) packages to use
- Which .NET version to use
- Each project in a given solution will have its own
.csproj
file. For example, in this walkthrough, your solution will have two projects:- The Blazor project
- A class library
- Visual Studio can use the
- Open Visual Studio and navigate to the screen to create a new project.
- When selecting the project type, choose Blazor Web App, and click 'Next'.
🧙 Wizard Wisdom: A Blazor Web App is a new project type as of .NET 8 that combines the best of Blazor Server and Blazor WebAssembly into a single application type.
- On the next screen, we are going to name both the project and the solution different things for sake of clarity. Name your project
TomeBlazorProject
and name your solutionTomeSolution
.- Choose a good storage location on your computer for your work in the Location field.
- Make sure that the checkbox labeled 'Place solution and project in the same directory' is NOT checked.
- The next screen gives us some additional control over how this Blazor project will be created. We can choose the version of .NET, an authentication type, etc. Make sure you're using the latest version of .NET you have installed (likely
.NET 9.0
). Do not change any other field except for ensuring the checkbox labeled 'Include sample pages' is NOT checked.
Assuming you have followed the instructions so far, you should now see a newly-created project and solution in the Visual Studio workspace. The Solution Explorer, likely located on the right side of your screen, shows you all of the projects inside of whatever solution you have opened.
🧙 Wizard Wisdom: Make sure that you're opening the
.sln
file when you're working on these projects (double-click it in File Explorer or open via Visual Studio's interface) as you will not be able to take advantage of the tools Visual Studio offers when working with projects if you fail to do so.
🧙 Wizard Wisdom: If you ever lose the Solution Explorer pane in Visual Studio, do not fret! Click
View
in the ribbon at the top, and selectSolution Explorer
to conjure it back! If you're a fan of hotkeys, you can also pressCtrl+Alt+L
to do the same thing.
We now want to create a second project as part of the solution. This second project will be a class library that will contain all of our model classes used in the Blazor application.
🧙 Wizard Wisdom: It is always a good idea to separate your code in ways that make sense for the given scenario; here, we are going to use some object-oriented programming to simulate a virtual book of creatures and plants. As such, it makes sense to put all of the classes and interfaces (known as models) in a separate project to keep our work organized and clean.
- Right-click on the solution in the Solution Explorer (should be called
TomeSolution
) and selectAdd
->New Project...
. This will take you the project creation screen. - Choose Class Library for the project type and click 'Next'.
- On the next screen, name this project
TomeLibraryProject
and click 'Next'. - On the next screen, make sure the latest .NET version is selected and click 'Create'.
Your solution explorer should now show two projects as part of the TomeSolution
solution: TomeBlazorProject
and TomeLibraryProject
.
🧙 Wizard Wisdom: Just because we have created a new class library does NOT mean that our Blazor project can access it. We need to add something called a project reference to our Blazor project in order to make that happen. And, as luck would have it, I am going to help you do that next!
By adding a reference to our newly-created class library project, we can allow our Blazor project to access the classes within it. This is necessary if we want to use our models in the Blazor application, which we absolutely do.
- Right-click on the
TomeBlazorProject
project in the Solution Explorer, and selectAdd
->Project Reference...
to open the Reference Manager. - In the reference manager, select 'Solution' under the 'Projects' group on the lefthand side of the window (this should be selected by default). You should see
TomeLibraryProject
here. Check the box next to its name, and click 'OK'.
You now have a project reference to your class library in the Blazor project! To verify that this worked, in the Blazor Project, expand the 'Dependencies' dropdown, then 'Projects', and you should see TomeLibraryProject
listed.
🧙 Wizard Wisdom: While we don't have any code written in either project yet, getting the references set up will help us out in the long run. The next steps of the walkthrough will detail setting up the class library and displaying some basic information via the Blazor app.
The bones of the project have been laid out, and now it's time to add some functionality.
Make sure that for this section, you're paying attention to which project you're adding files to. Because they're both open in the Solution Explorer, it's important to keep track of what you're working on.
🧙 Wizard Wisdom: It can be helpful to collapse the dropdown of the project you're NOT working on in the Solution Explorer to keep it out of mind for the moment.
- Your class library may have a
.cs
file inside of it (likely calledClass1.cs
). Delete this file if it exists. - For each of the classes in the following UML diagram, right-click on the class library project, and select
Add
->Class
and make sure that 'Class' or 'Interface' is selected depending on what you're adding.- Note that the
Rarity
class is labeled as anenumeration
orenum
. Add a new class calledRarity
. The next step will discuss implementing anenum
in its own class file.
- Note that the
- After adding each of the classes and interfaces, add the properties shown in the UML. Make sure that you're paying attention to their accessibility (
+
meanspublic
) and that the relationships between classes are being implemented properly.- Change the
internal
keyword in all of the added classes/interfaces to thepublic
keyword. - Change the
class
keyword inRarity.cs
to theenum
keyword. See below for the contents ofRarity.cs
.
- Change the
namespace TomeLibraryProject
{
public enum Rarity
{
Common, Uncommon, Rare, Legendary, Mythical
}
}
🧙 Wizard Wisdom: Make sure you are creating the attributes of the classes as properties with a
public
modifier and a{ get; set; }
after each one. You can typeprop
and hit the tab key in Visual Studio if you'd like a keyboard shortcut.
classDiagram
class Rarity {
<<enumeration>>
Common
Uncommon
Rare
Legendary
Mythical
}
class IOrganism {
+string Name
+string ImageUrl
+string Description
+Rarity Rarity
}
class ICreature {
+string Habitat
+bool IsHostile
}
class IPlant {
+bool IsMedicinal
+string BloomSeason
+bool IsPoisonous
}
class Creature {
+string Name
+string ImageUrl
+string Description
+Rarity Rarity
+string Habitat
+bool IsHostile
}
class Plant {
+string Name
+string ImageUrl
+string Description
+Rarity Rarity
+bool IsMedicinal
+string BloomSeason
+bool IsPoisonous
}
Rarity <|-- IOrganism
ICreature --|> IOrganism
IPlant --|> IOrganism
Creature ..|> ICreature
Plant ..|> IPlant
🧙 Wizard Wisdom: Make sure that you're following the naming conventions of the UML diagram (e.g., for the
BloomSeason
property in thePlant
class, that line of code might look like the following:public string BloomSeason { get; set; }
). Failure to follow the proper naming convention for these properties will result in some issues for you later in this walkthrough.
Now that we have a model, let's add a Service to the Blazor project to use these classes to show some data on a webpage.
- Ensure that you are working with the
TomeBlazorProject
project in the solution explorer. - Add a new class to the Blazor project called
OrganismService
. - Paste or write the following code into
OrganismService.cs
.
using TomeLibraryProject;
namespace TomeBlazorProject.Services
{
public class OrganismService
{
public Creature GetSampleCreature() => new Creature
{
Name = "Skywhale",
ImageUrl = "https://t4.ftcdn.net/jpg/08/28/33/25/360_F_828332571_NeEXZmhJ19tQ2CybnLwLPEUTQ7WtRbMr.jpg",
Description = "A gentle giant that floats above the clouds.",
Habitat = "Sky Isles",
IsHostile = false,
Rarity = Rarity.Legendary
};
public Plant GetSamplePlant() => new Plant
{
Name = "Moonblossom",
ImageUrl = "https://www.socalcamelliasociety.org/Camelliae%20Floris%20Bibliotheca/images/Moon%20Blossom.jpg",
Description = "A glowing flower that only blooms at night.",
IsMedicinal = true,
BloomSeason = "Winter",
IsPoisonous = false,
Rarity = Rarity.Rare
};
}
}
🧙 Wizard Wisdom: While we will be changing the functionality of this service later, it is useful for now to generate a new object of the
Plant
andCreature
type and return it (e.g., the=> new Plant
code means thatGetSamplePlant()
will return a newPlant
object that is instantiated via the code inside the braces.
- Register the service in
Program.cs
in the Blazor project by pasting the following code after thevar builder = WebApplication.CreateBuilder(args);
line and before thevar app = builder.Build();
line.
builder.Services.AddSingleton<OrganismService>();
🧙 Wizard Wisdom: Registering a service with your app essentially tells Blazor that you want to use that class anywhere in the app. Depending on the lifecycle you choose (in our case a singleton), Blazor will then make it available as needed per that lifecycle.
- Display the data with
Home.razor
by replacing the contents ofHome.razor
with the following code.-
Home.razor
can be found in/Components/Pages
in your Blazor project.
-
@page "/"
@inject TomeBlazorProject.Services.OrganismService OrganismService
<h1>Magical Field Guide</h1>
<h2>Creature</h2>
<div class="organism-card">
<h3>@Creature.Name (@Creature.Rarity)</h3>
<img src="@Creature.ImageUrl" alt="@Creature.Name" />
<p>@Creature.Description</p>
<p><strong>Habitat:</strong> @Creature.Habitat</p>
<p><strong>Hostile:</strong> @(Creature.IsHostile ? "Yes" : "No")</p>
</div>
<h2>Plant</h2>
<div class="organism-card">
<h3>@Plant.Name (@Plant.Rarity)</h3>
<img src="@Plant.ImageUrl" alt="@Plant.Name" />
<p>@Plant.Description</p>
<p><strong>Bloom Season:</strong> @Plant.BloomSeason</p>
<p><strong>Medicinal:</strong> @(Plant.IsMedicinal ? "Yes" : "No")</p>
<p><strong>Poisonous:</strong> @(Plant.IsPoisonous ? "Yes" : "No")</p>
</div>
@code {
private Creature Creature;
private Plant Plant;
protected override void OnInitialized()
{
Creature = OrganismService.GetSampleCreature();
Plant = OrganismService.GetSamplePlant();
}
}
- You should have a file called
app.css
in thewwwroot
directory in your Blazor project. This CSS file is linked by default in/Components/App.razor
. Add the following code toapp.css
.
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f9f9f9;
margin: 0;
padding: 0;
color: #333;
}
h1, h2, h3 {
color: #2c3e50;
}
div {
margin-bottom: 2rem;
}
.organism-card {
background-color: white;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
padding: 1.5rem;
max-width: 600px;
margin: 1rem auto;
text-align: center;
}
.organism-card img {
max-width: 100%;
height: auto;
border-radius: 8px;
margin-top: 1rem;
margin-bottom: 1rem;
}
.organism-card p {
margin: 0.5rem 0;
}
🧙 Wizard Wisdom: Feel free to change any of this CSS to be to your liking. The
organism-card
classes are not necessary in your HTML, and are simply included in this walkthrough as a styling baseline/example.
- Run the Blazor project and verify that you can see the two objects displayed in the browser. If you can, congratulations -- you're done! If not, make sure that you go back over the instructions.
- If you run into any issues with the code I provided, the problem is likely found in your implementation of the classes, interfaces, and enum in the class library.
Congratulations! You have completed Act I of this walkthrough. There will be more to come, but this is likely going to be one of the more involved pieces of this app development. If things aren't working properly, make sure that you've followed the instructions carefully.
If there is an issue with these instructions, please let them be known! Stay tuned for more, and thank you for your time.