Course Information
Course Overview
ASP.NET Core is not difficult! My Projects of easy steps are more than sufficient for a quick and practical transition!
ABOUT ME
I am a programmer/developer of more than 30 years' experience, in C++, Win32 API , Java, Android apps, C# Desktop applications on security, C# ASP.NET classic, C# ASP.NET MVC , and now I am busy with ASP.NET Core and Raspberry PicoW C++.
ABOUT THIS COURSE
(CAN BE USED AS A REFERENCE BOOK)
SOURCE CODE PROVIDED FOR ALL PROGRAMS, EXERCISE SOLUTIONS AND PROJECT
This is a beginner's course in ASP.NET Core.
Projects covered (see the linked videos):
1. Find a Doctor
2. LAN based classroom voting project
3. Billing, Inventory and Shopping with bar codes
4. Location Tracking Project
5. IOT based switching
6. Realtime Auction with SignalR, WebApi and Javascript
7. Realtime ESP32 IOT Switching with Azure PubSub Web Service
8. Cinema Ticket Booking Application
9. Authentication and Login with a USB Doggle
10. Handwriting to Text with Azure AI Vision API
☞Ch1 - RAZOR PAGES
Beginner's Introduction to Razor Pages
This is the simplest introduction to Razor Pages - why you need them, what they are, and how page events and data could be handled with them. See the linked video for a primer information.
Integrating CSS and JS Files with Razor Pages
This is a quick and complete explanation of how to integrate your razor pages to a framework such as bootstrap, and how to add and manage your custom CSS, JS and image files in your application. We explain various files such as the _ViewStart file, the _Layout file, and the special directory wwwroot. The concept is similar to that of master pages in the classic ASP.NET. The article also contains a linked video that you can watch for a clearer understanding of how we have integrated bootstrap to a simplest ASP.NET Core application.
Inter Page Navigation and Linking of Razor Pages with Anchor Tag Helpers
Tag helpers provide a standard way of generating html tags in razor pages. They are interpreted on server side. They are of the same syntax as html tags, so a web-designer can style and script them as he does any other html tag. Razor pages are not enabled for tag helpers by default. In this tutorial we learn how to enable a razor page for tag helpers, and we also learn a walkthrough on using the most common "anchor tag helper" to navigate from one razor page to another.
☞EXERCISES ON Ch1 - RAZOR PAGES
Exercise 1.
Create an application consisting of a razor page called Index - but without its backing csharp file. The razor page should print your name.
Exercise 2.
Display your name thus: Add a string variable called strName to the page in Ex 1. Set the variable to your name. Then display the variable strName.
Exercise 3.
Create an application consisting of a razor page called Index - but without its backing csharp file. Create two int variables i and j. Set i to 7 and j to 2. Display their sum using razor syntax.
Exercise 4.
Add a function called, say, GetName to the razor page in the first exercise. The function has a return type of String and returns your name. Now display your name by calling the above function.
Exercise 5.
Create an application consisting of a razor page called Index and its backing csharp file. Create two int properties i and j in the backing class. Set i to 7 and j to 2. Display their sum using razor syntax.
Exercise 6.
Without using razor pages, write a simple ASP.NET Core application that writes a "Hello World!" message to the response stream when an HTTP GET request is made to the home page of your website.
Exercise 7.
Without using razor pages, write a simple ASP.NET Core application that sends a FORM consisting of an input textbox and a submit when an HTTP GET request is made to the home page of your website. The application should handle the posted data and respond by sending back the upper case equivalent of the input typed by the user.
Exercise 8.
Create an application with a layout file [full head, body html tags] that shows the current system time in a h1 tag. The file connects to a CSS file called "mycss.css", which is placed in a wwwroot directory, and has a class for a p tag that sets its text color to red. Create a razor page called index that shows your name in a "p" tag. This page should merge into the layout file. Run the app to verify that your name appears in red.
Exercise 9.
Many CSS frameworks like bootstrap are available on the internet. Find any framework of your choice and create a layout file [full head, body, html, etc.,] by linking its CSS/JS files. Then create two pages - Index and Products. Each page has the same two buttons called "Home" and "Products". When Home is clicked the user should be taken to the Index page, and when Products is clicked the user should be taken to the Products page.
☞FIND A DOCTOR PROJECT - STEP 1
This is now an implementation of the concepts learnt so far, where we start with a new project and add three razor pages - Index, Login and Register. Layout and viewstart files use the CSS/JS based bootstrap library to provide "color" to the pages. Tag helpers are used for inter page navigation.
☞Ch1A - ASPNET CORE APPLICATION STARTUP (can skip for later)
Environments in ASP.NET Core
This tutorial explains about the various environments like Development, Staging and Production. We also explain how to set them by various methods and how to conditionally check for environments and perform settings.
Kestrel, IIS, IISHttpServer and HTTP.sys
An ASP.NET Core application cannot directly accept requests from the internet. For this it needs a server that can face the internet and help it communicate with the calling client on the other side. This means that some sort of coupling is required with a server software. This tutorial discusses various possibilities. Discussion of the launchSettings file is reserved for the next tutorial.
The launchSettings.json File and launch Profiles
We learn about the finer details of launchSettings.json file. This file contains various launch profiles to start an application in various modes - such as InProcess, OutOfProcess and direct Kestrel. Visual Studio uses this file to populate a dropdown toolbar so that the application can be started in various modes at the click of a button. This allows for easier debugging and testing of an application.
Logging in ASP.NET Core
Logging helps in troubleshooting, it helps in audit, it helps in getting signals of an imminent application crash. This topic explains the terminology of a log message, and also explains how to configure an application for logging, and also how to observe a sequence of log messages.
Storing and Reading Configuration Key Value Data
We have seen in the previous tutorials that appSettings json file can be used to configure log levels. But this is not the only use of this file - it can, as well, be used to store custom key value data that can be read anywhere in your application. It turns out that log levels are just one of the possible values - there is a lot more that can be done. In this tutorial we shall learn how to store some rudimentary data and then read it back on a razor page.
Using Options Pattern to Read Configuration
In the previous tutorial we read various properties of an appSettings configuration file. But there is a better method for reading complex properties - such as "Address" - that we read in the previous tutorial. This is done through the options pattern. Let us now read City and ISDCode of the Address property by using the options pattern.
What and Why of the UseDeveloperExceptionPage Middleware
We shall create an app using visual studio 2022, running .NET 6. The application will artificially throw an un-handled exception. Then we shall verify that if the application is running under development, then asp.net core automatically provides a safety net to handle this exception, and provides a detailed information about the error. But if the same application is in, say, production, then there is no developer exception page, and the application crashes midway, with no response sent.
Writing a Custom Exception Page and the UseExceptionHandler middleware
This tutorial continues our previous tutorial where we learnt that if an application is running under development environment, then ASP.NET Core provides a UseDeveloperExceptionPage middleware that catches un-handled exceptions and provides a detailed information about the snapshot state of the application. But that feature is not recommended for production environment - a developer should provide a custom page to filter out the information that finally reaches the display. Let's learn how!
☞Ch2 - BASIC EVENT HANDLING IN RAZOR PAGES
How to handle a click event in Razor Pages
An anchor tag helper can be used to specify the name of the click event handler. For this the attribute "asp-page-handler" is set equal to the name of the function in the backing class. Read through this tutorial to understand the whole idea. A video is also attached for a first-hand explanation. The tutorial concludes with a walkthrough that demonstrates how a click event can be handled on the server side.
Creating an HTML FORM with Razor Pages
This is an introduction to the most common UI Elements that can be used on a FORM. The article starts with a quick introduction to an html form of only one textbox, and then shows how to translate it to a razor form. Then a checkbox, a radiobuttonlist, and a dropdown are successively added one by one to build a full blown razor form. Data is not posted, a topic reserved for the next tutorials.
How to handle a FORM submit event
A form submit is triggerred by a submit button inside FORM tags. If the method is POST, which is most often the case, then the recommended handler is OnPostAsync. The method should be asynchronous because FORM data is invariably processed through database INSERT and UPDATE queries, which must be done asynchronously. The submitted data can be extracted through the two-way BindProperty. See the linked video for a better understanding.
Program Example on Data Display and FORM Update
(LEVEL IS BEGINNERS) Suppose there is a model called StudentData with properties ID, Name, School and Marks. Also suppose we already have a collection of StudentData records with the first three properties already filled, and Marks is NULL. Write an Index page to display the data of the students in a table of 5 columns. The fifth column contains a link button called Edit. When the link is clicked, the user should be taken to a page called Edit. The Edit page contains a form where Name and Marks can only be edited. Update the collection when the form is submited and redirect the user to the index page to show the updated record.
How to handle Server Side Validation
This article starts with a brief primer on server side validations and why they should be done. A simple model of just one property is used to explain the whole process - starting from setting the validation error messages to finally inserting validation tags to render the errors. We explain how "asp-validation-for" attributes can be used to display validation errors, and that too, respectively, for each property and at a location just adjacent to its FORM element(see the screenshot below), and also how the ASP.NET Core engine takes care of almost 99% of your work. We also explain how to, optionally, display a gist of all validation errors using the "asp-validation-summary" attribute.
☞EXERCISES ON Ch2 - Basic Event Handling in Razor Pages
Exercise 1.
Create an ASP.NET Core application that has a razor page called Index, and that shows an anchor "Click Me!". When the anchor is clicked the anchor should disappear and it should be replaced by the message "I am clicked". Write the entire code in the Index.cshtml razor page - no backing class is to be used.
Exercise 2.
The first exercise can also be solved by sending an arbitrary querystring parameter when the anchor link is clicked. The "Request" can be tested for the presence of that parameter in a conditional "if" statement, and accordingly render the message or the anchor. You might have to google about how to send query string parameters with an anchor tag helper. Then you can google about how to read query string parameters in a razor page.
Exercise 3.
Instead of following the approach in Ex. 2 above, another alternative to sending a query string through an anchor tag helper is to send a query string by using an overload of "RedirectToPage". Implement this scheme by redirection from the click event handler.
Exercise 4.
Solve Ex. 1 without using the addTagHelpers directive.
Exercise 5.
Create a FORM of two inputs that, respectively, accept two numbers - say, i and j. The submit event should be handled by the backing class and the sum returned through a query string parameter. Display the sum on the same FORM.
Exercise 6.
Create a FORM of two inputs that, respectively, accept two numbers - say, i and j. Display the sum on the same FORM but without using a query string.
Exercise 7.
Create a login form of two inputs - UserName and Password. Show a message "Login succeeded" if the user enters UserName as "u", and Password as "p". Otherwise show the message "Invalid credentials". The message should appear somewhere on the same form.
Exercise 8.
Create a razor page of two forms on the same page. Each form has one input textbox and a submit button. The first form has a textbox for first name, whereas the second form has a textbox for last name. Initially only the first form is visible. When the user submits the form, the first form hides away and the second form becomes visible. When the user submits the second form, it too is hidden and a message showing the full name should appear instead. Hint: on the basis of what you have learnt so far, you might have to use an input of type="hidden".
☞FIND A DOCTOR PROJECT - Step 2
Event handlers for Login and Registration buttons are connected now. Two model classes RegistrationInfo and LoginInfo are added to connect the registration and login forms to the respective OnPostAsync handlers. We verify that FORM data is indeed being received, and server side validation and validation summary are functional. We are now at the point of database connectivity where we shall register the user.
☞Ch3 - DATABASE CONNECTIVITY - I
Getting Started with Database Connectivity
Here is a to-the-point tutorial on how database connectivity works in ASP.NET Core. A 3-step roadmap is laid for running your first query to a database of your choice. The tutorial concludes with an example walkthrough on adding nuget packages for a sqlite database. The actual database connectivity is done in later tutorials.
Getting Started with Database INSERT of Form data
A form of only one input textbox is POSTed and the data is inserted into a sqlite database. This is a six step walkthrough that starts from creating a model, followed by a DAL based on the DbContext class. We also explain how an application is configured for dependency injection of the DbContext, and also, how the DbContext is extracted from the constructor of a PageModel class, and ultimately used to run a database query.
Strategy to handle a DbUpdateException
SaveChanges can fail if a constraint fails, if a connection error occurs or if any generic error occurs. So it should always be wrapped in a try-catch handler to gracefully handle the DbUpdateException. But how to inform the user about such a failure? One way is to use the built-in server side validation to artificially push the error as a validation failure.
Specifying Primary Key (s) and the DbSet.Find() method
This is a brief explanation of how to specify single primary key on a model through attributes - but this approach fails when multiple columns are to be set as the primary key. We explain that such a composite primary key has to be set through the DbContext. Finally, we explain how to query a record on the basis of its primary key.
Displaying Data and OnGetAsync
This tutorial continues from where we left the tutorial on INSERT query (see the link below for a recap). The code we discussed there has been extended to display the inserted data. In the first part of this tutorial we explain the minimal three basic things that must be done to display data on a razor page. Then we incorporate those additions into the index page and its backing class to show the whole idea in action.
Deleting Records from a Database with EF Core
We start by explaining the general scheme for deleting a record from a table. A foreach loop adds an anchor link to each record. The primary key (id) of each record is set as an attribute of each respective anchor link, and each anchor link also binds to a handler function in the backing class. When such a link is clicked the handler receives that id as a parameter and a C# code carries on the deletion.
Editing Records on the same Razor Page with EF Core
This tutorial discusses the most desired scenario where data entry form and the already existing records are shown on the same page. Each record has an edit link adjacent to it. When this link is clicked, the record appears in the same data-entry form, so that the user can make changes and submit it. See the image below for a quick understanding of the problem being addressed here. This tutorial also explains a general scheme for editing with EF Core.
CRUD with a Checkbox in a Razor Form
This tutorial extends the one-textbox FORM that we have implemented for CRUD operations in the previous tutorial (see link below). Now we add a checkbox to that form and observe how easy is it to make an addition to a project that is already CRUD-ready!
CRUD with a Radiobuttonlist in a Razor Form
This tutorial extends the FORM that we have implemented in the previous tutorial (see link below). Now we add a radiobuttonlist to that form and observe how easy is it to make an addition to a project that is already CRUD-ready! The radiobuttonlist is backed by a hard-coded C# enumeration. We also explain how to specify the conversion from an enum to an INT data-type on the database side.
☞EXERCISES ON Ch3 - Database Connectivity - I
Exercise 1.
Write down all the steps needed for the initial setup for connecting to a Sqlite database.
Exercise 2.
Create a model - called, say, MyModel - that has a primary key property of string datatype - called CountryID - and another property of string type - called DisplayName. Both the properties should be marked as required. Create a form (complete with inputs, submit and validation spans) that helps you save records of type "MyModel" to a table of sqlite database. Your code should gracefully handle a DbUpdateException. Test your project by adding a few records, and also verify that duplicate CountryID cannot be saved to the database. Note: Primary key of string datatype must be marked as DatabaseGeneratedOption.None, otherwise it will not work because the default is DatabaseGeneratedOption.Identity.
Exercise 3.
Create a form of one textarea and a submit button. This form is to be used for bulk insert of records of type "MyModel" [see previous exercise] to a table of sqlite database. This is how the form will be used: a user will type rows of records in a semi-colon separated format, for example Brazil may be typed as BZ;Brazil, where "BZ" is CountryID and "Brazil" is the DisplayName. When the form is posted, the rows should be read in a loop and each record extracted, and inserted into the database. Finally, a summary of the number of records succeeded and that failed should be shown somewhere on the same form.
Exercise 4 [checkbox insert and display]
Create a razor page that has a FORM of two inputs - first a textbox for the name of a player and second a checkbox "Plays Chess". When the form is submitted, the data is stored in a table. The same razor page should separately display the lists of chess players and non-chess players. We suggest that a three column layout be created using suitable CSS. The left column should show non-chess players, the middle column should show the data entry FORM and the right column should the chess players. Note: You will need to use the ".Where" LINQ for filtering chess players.
Exercise 5 [toggle transfer between lists]
Extend the above exercise thus: Add an anchor link (called, say, "move to non-chess players") adjacent to each record of chess players. When this anchor is clicked the chess playing status of the player should be toggled so that the same player gets "transferred" to the list of non-chess players. Similarly add an anchor link adjacent to each record of non-chess players. Run the project and verify that "transfers" actually happen.
Exercise 6 [seed random data]
Create a model class having three properties - ID [auto int PK], FirstName, LastName and DateOfBirth - the last one being of the DateTime datatype. Configure your project for sqlite database connectivity. The Index razor page should have an anchor link called "Insert 10 random Records" and connected to a function "SeedData". Just below the anchor link, the data is displayed in an html table of four columns - ID, First Name, Last Name and Date Of Birth. Run the project to verify that each click adds 10 random records to the table. Note: you can use the Random class to generate random ASCII text.
Exercise 7 [pagination]
Add paging to the previous exercise by adding "Next", "Prev" anchors below the table. Take a page size of, say, 7. "Prev" link should be disabled on the first page, whereas the "Next" should be disabled on the last page. Use suitable CSS to disable an anchor link.
Exercise 8 [sorting]
Add sorting to the previous exercise by replacing the Date of Birth heading with an anchor link. When the anchor is clicked repeatedly, the sort order changes from ascending to descending, and vice versa. Test it thus: First run the project to verify that paging works and the sort order is the default order as seen from the sequence of ID. Now move to the next page and click the Date Of Birth heading. The table should now reset to the first page, but the list should display as sorted. Now click on the Next link [and then back and forth] to verify that the remaining records can be seen in the same sorted order.
☞FIND A DOCTOR PROJECT - Step 3
The project has now been configured for database connectivity through Sqlite. The Registration module is fully functional - a user can register as a doctor or a patient - and a database INSERT entry is now working. EMail ID is the primary key. If a record already exists then a DbUpdateException is handled and failure is shown through a validation summary. If the registration is successful, the user is redirected to the login page. If he logs in with wrong email/password then he is asked to ammend and retry. But if he logs in with an email that isn't registered yet, then he is asked to register himself. Next we learn how to consolidate the code through ViewImports.
☞Ch4 - MODULARITY
_ViewImports file and the do's and don'ts
_ViewImports.cshtml is shared by all the razor pages in its peer directory, and in the sub-directories below it. It is like an include file, and it is used to type a list of common directives that would otherwise have to be typed in each of the razor pages. A razor page takes into account the entire hierarchy of _ViewImports files above it.
Razor Components in the Context of Razor Pages Apps
Razor components are stand-alone, embeddable units that replace themselves with pure HTML, CSS and JS markup. They can accept parameters from the host page. We discuss below how they differ from partial pages, and we also discuss the structure of a component page, and also how to use the <component> tag to easily embed a component into a razor page.
☞EXERCISES ON Ch4 - Modularity
Exercise 1 [print name, razor components]
Write a razor component that has a function called "GetName" that returns your name as a string. The razor component displays your name by calling this function. Embed this component in your index.cshtml razor page to display your name.
Exercise 2 [count chars in a string, razor components]
Write a razor component that takes two parameters - HostName and CharToCount. The first parameter is the name of a website - like microsoft - without the prefix "https://" and the suffix ".com", and the second parameter is a character, such as 'A'. Your razor component will send a hit to https://{HostName}.com and download the page as a string, and count the number of {CharToCount} in that string and display the characters counted. Use this razor component in a razor page that has a form that accepts HostName and CharToCount as inputs from the user. When the user submits the form, these inputs should be passed to the razor component to display the number of characters found. Hint: use an HttpClient request in "OnInitializedAsync" to download the string and count the chars. You might want to review the tutorial L02 - Razor Components where makeSquare function has been discussed along with passing parameters.
Exercise 3 [general purpose table component]
Write a razor component called Table.razor that accepts three parameters - a string array String[] for its heading row, a String[][] array for the remaining rows to display the data, and a third parameter for css class to be applied to the table. So this is a flexible table that can be re-used in any project. Use this component in a razor page to render a table of three columns - ID, Name and Phone. The data can be of, say, two records. Also pass a css class as a parameter so that the table gets a pleasant look.
Exercise 4 [click event in a razor component]
A razor component can handle and process a click event if it is written as a blazor component. Refer the attached blog link and the linked youtube video to see the basic steps needed for this integration. After that write a component that displays a new quote, each time its button is clicked. Use a String array to hold a few quotations so that a user can click and cycle through them.
☞FIND A DOCTOR PROJECT - Step 4
In this step we tidy the Index.cshtml, Register.cshtml and Login.cshtml razor pages by moving various common directives (like addTagHelper) and namespaces to a viewimports file. This practice will now be followed throughout the remaining project. Now we are ready to write the home page of doctors.
☞Ch 5 - AREAS AND PARTIAL VIEWS
Concept of Areas and an Authorization Scheme
This is a comprehensive discussion on the need for "areas", and how to practically create "areas", and how, un-like classic MVC, routing occurs out-of-the-box when razor pages are used. We also discuss how tag helpers help us create proper anchor links to pages inside areas. In the end we present a practical login and authorization scheme for projects that use areas.
Partial Views from a Practical Perspective
So this article starts by explaining the various aspects of a partial view from a practical, day-to-day perspective. We have totally removed those parts that are either redundant or too complicated to be of any use for a practical developer. Then we take a small 3-step walkthrough that shows how to create a partial view, and how to consume it in a razor page. We also explain how a conditional menu can be conveniently implemented using the ideas of partial views. Partial Views + Razor Components can add to the confusion of a developer, so we finally conclude with a comparison with razor components.
☞EXERCISES ON Ch5 - Areas and Partial Views
Exercise 1 [simple partial]
Create an application that has a razor page called Index. Now add a partial page called _MyPartial that displays your name in an h1 tag. Use this partial in the Index page to display your name. The helper directives should be placed in a view imports file.
Exercise 2 [navigation to area]
Create an application that has a razor page called index containing an anchor link. Add an Area called Albums. Inside this area there is an Index razor page that displays a welcome message in, say, an h1 tag. When the beforementioned anchor link is clicked, the user should navigate to the index page of the Albums area.
☞FIND A DOCTOR PROJECT - Step 5
Two "Areas" are added - Doctor and Patient. The pages relevant to a doctor shall stay in the former, whereas of a patient in the latter. Home pages have been added for both. Partial pages for _Header, _Menu and _Footer have also been added for the doctor's area, and similarly partial pages for _Header and _Footer are added for the patient's area. This is what happens now: when a user logs in, then depending on the UserType he is redirected to his "Area". Next let us learn about Authentication and Authorization so that the users of a specific "Role" can only access the pages.
☞Ch6 - STATE MANAGEMENT
Reading, Writing and Deleting Cookies in ASP.NET Core
We start this walkthrough
Course Content
- 10 section(s)
- 266 lecture(s)
- Section 1 Ch Zero - List of Projects Covered
- Section 2 Chapter First - ASP.NET Core Quick Start in 70 minutes
- Section 3 Ch 1 - Razor Pages
- Section 4 Exercises on Ch1 - Razor Pages
- Section 5 Find a Doctor Project - Step 1
- Section 6 Ch1A - ASPNET Core Application Startup (can skip for later)
- Section 7 Ch2 - Basic Event Handling in Razor Pages
- Section 8 Exercises on Ch2 - Basic Event Handling in Razor Pages
- Section 9 Find a Doctor Project - Step 2
- Section 10 Ch3 - Database Connectivity - I
What You’ll Learn
- IN NUTSHELL: SEE CHAPTER ZERO BELOW. It contains all the projects! The projects will give you a reason to buy this course for learning ASPNET Core!
- Project 1 - Find a Doctor Project
- Project 2- LAN based Classroom Voting Project
- Project 3 - Youtube Downloader Project with youtube-dl
- Project 4 - Billing, Inventory and Shopping with BarCodes, Project 5 - Location Tracking Project, Project 6 - IOT based Switching
- Modular design with Areas, ViewImports, Layouts, Partial Views and Razor Components
- Identity and Role based Authentication and Policy based Authorization, Authentication with AJAX Requests.
- AJAX communication with ASPNET Core, Minor project on EBook style Admin panel, Ajax based inline, in-place edit, update and cancel of tabular data
- A project "Find a Doctor" is completed as the course progresses. This project covers all the common scenarios that a web developer has to deal with. . .
- Identity, Two/Multi Factor Authentication, Docker, Middleware, Migrations, WebApi
Reviews
-
KKrishnaveni
i think its waste of my time
-
AAjeet Kumar
The trainer is very experienced and has created very structured course which is best for beginners. The exercises used in the video are very good to learn concepts step-by-step.
-
PPuneet Chandiok
I like the way all the concepts are explained with examples up to the minutest detail. Thanks
-
AAlex R
Top quality content!