C# ASP.NET Core 7 + MVC, Razor Pages + Exercises + Projects

ASP.NET Core is not difficult! My Projects of 7/8 steps are more than sufficient for a quick and practical transition!

C# ASP.NET Core 7 + MVC, Razor Pages + Exercises + Projects
C# ASP.NET Core 7 + MVC, Razor Pages + Exercises + Projects

C# ASP.NET Core 7 + MVC, Razor Pages + Exercises + Projects udemy course

ASP.NET Core is not difficult! My Projects of 7/8 steps are more than sufficient for a quick and practical transition!

What you'll learn:

ASP.NET Core Razor Pages + Machine Learning (Project Based)

  • Create ASP .NET Core Razor Pages web application from scratch.
  • Create a Machine Learning Model in .NET/.NET CORE
  • Consume a Machine Learning model from an ASP .NET Core Razor Pages web application
  • Get used to Dependency Injection and repository pattern
  • Understand and use EntityFrameworkCore

Requirements:

  • No programming experience is needed. Everything will be explained

Description:

WHAT'S NEW

Note: my projects are more than sufficient for a quick and practical transition to ASP.NET Core

Jan 6, 2023 - Billing and Inventory Bar code Project (.NET 7 and C#11 or later)

Dec 19, 2022 - Youtube Downloader Project with SignaR (.NET 7 and C#11 or later)

Dec 3, 2022 - LAN based Classroom Voting Project (.NET 7 and C#11 or later)

Nov1, 2022 - Added Lecture "Example on Data Display and FORM Update" under Chapter "Ch2 - Basic Event Handling in Razor Pages"

Oct 15, 2022 - Added Chapter - EFCore Best Practices and Performance (8 tutorials)


(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.

About the Project

  1. Registration and Login Modules

  2. Role based Authentication and Authorization

  3. SQlite as Database.

  4. MySQL integration of the completed project is fully explained LIVE in 22 minutes

  5. Doctors and patients can update their profiles and pictures

  6. Patients can search for doctors of various specializations and in various cities.

  7. AJAX based cascading dropdowns for search

  8. JSON based database of cities

  9. Patients can upload PDF reports

  10. A consultation and a payment loop is fully built in this project.

  11. Bootstrap based UI

Even though the project is "Find a Doctor", but it can be thought of as a "customer-service provider project". Hence, it can be modified for a website where customers search for plumbers, technicians, etc., or for a website where students search for teachers of various subjects.


☞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 with a small introduction to the concept of a cookie, and then we explain the various ASP.NET Core snippets to (a) create a cookie, (b) read a cookie and (c) delete a cookie. And lastly, we create a fully functional application for creating and deleting cookies. You can run the application to see the whole concept in action! We strongly recommend that you watch the linked video for finer details.

Cookie Consent Banner with ITrackingConsentFeature

This is a walkthrough on how to obtain user consent for usage of cookies on an asp.net core website. This project uses the ITrackingConsentFeature interface to determine if the user has already given his consent, and also to obtain the correct cookie string as per the http format. The readymade functions of this interface make it extremely easy for a developer to obtain a user's consent.

How to use Session for State Management

This article explains behind-the-scenes mechanism by which "Session" is implemented in ASP.NET Core. We also enumerate the four extension methods that ASP.NET Core provides for reading and writing session variables. After that we present a walkthrough where existence of a Session key is checked to conditionally show a login link, or to show her user-name along with a log-off link that clears the user-name from the Session cache.

Serializing DateTime into Session

There is no built-in method for storing DateTime into a session variable in ASP.NET Core. However, the Microsoft MSDN docs suggest that developers can create their own extension methods on ISession, and they have provided code for one such pair of Set<T> and Get<T> methods that use json serialization to store any serializable type as a string. We have copy-pasted their code, and used it to create a small walkthrough that demonstrates how a DateTime instance can be stored in a session variable.

When and how to use TempData

TempData can be used to pass data from one razor page to another. Although QueryString and Session variables can be used to achieve the same objective, yet TempData provides a briefer and cleaner way, and most importantly, it is built into the ASP.NET framework. The most attractive feature of TempData is that the data is automatically cleared away after a first read/extract operation - whenever it takes place. The tutorial ends with a walkthrough where TempData is saved in one page and used for showing a message on a second page. The message appears only once.


☞Ch 7 - AUTHENTICATION AND AUTHORIZATION

Configuring Role based Authorization

This is an explanation of how an "Area" based ASP.NET Core project can be configured for role and policy based authorization. Authorization can be applied to the entire "Area" directory. We also explain how to specify the login and access denied pages.

SignIn, ReturnUrl and LocalRedirect

This article starts with an explanation of "SignIn", and then explains the various steps for a signin process. Finally, we discuss what is a returnUrl, and what is LocalRedirect, and when should it be used.

Displaying User Info on each Page he visits

This is a snippet on showing "You are logged as ..." on every page that an authenticated and authorized user visits. The code can be inserted in a razor page or in a partial page.

SignOutAsync with Tag Helpers

Following is a brief scheme on signing out a logged-in user. A function for sign-out is written in the same file as for the login code. Then this function is called from the click of some anchor link and "SignOutAsync" called to kill the login cookie. Finally, a redirection is done to the login page.


☞FIND A DOCTOR PROJECT - Step 6

Policy based authorization has now been applied. A logged-in doctor ONLY can view the pages of the "doctor" area, and similarly, a logged-in patient only can view pages of his area. RememberMe is also functional now - such a user is directly taken to the home page of his area. Email of a logged in user is now shown on each page he visits. Code for sign-out has also been added. With this the project is now fully functional for login, registration and the sign-out modules. We leave it as an exercise for the student to add a "Change Password" module.


☞Ch7A - IDENTITY IN ASPNET CORE (can skip for later)

Collecting the Pre-requisites for Identity based Authentication

We shall create an identity based project from scratch. Although, visual studio provides a scaffolding for all the various modules, but personally I find all that very difficult to integrate with my own projects and my own css files. That's the motivation for starting from scratch. It will be a series of tutorials. In this first tutorial, I shall add nuget packages, followed by an IdentityDbContext, and finally run a migration to create the database on local sql server.

Adding a Login Page to an Identity based Authentication Project

This tutorial shall continue from the previous tutorial where we have made a basic initialization, and we have also created a database to hold the data of our users. In this tutorial we shall make additional configuration to specify our login and access denied pages. We shall also add a restricted (or protected page) and verify that when an un-authenticated user tries to access it, then he is automatically redirected to the login page.

Adding a Registration Page to an Identity based Authentication Project

The problem with the built-in registration page provided by ASP.NET Core Identity API is that it contains a lot of tags and bootstrap attributes that make it time consuming to integrate it into a project that doesn't use bootstrap or jQuery. The objective of this article is to explain how to create a neat and simple registration page that can be styled with any css and javascript of choice. We use a simple html table to create a form, but we will not use any css and client side validation because that can always be done with the web designer teams.

Account Verification in an Identity based Authentication Project

Recall from the previous tutorial that in our program.cs file we have set SignIn.RequireConfirmedAccount = true. This prevents immediate login to a newly registered user. The user is compulsorily required to verify his account through an email or SMS sent to his phone. For this, a link containing a specially generated confirmation token is sent to him. When the user clicks this link then this token is verified on the server side, and the user is informed of the confirmation status.

Resending an Account Verification EMail in Identity based Authentication

As soon as a new user registers on a website, an account verification email or an sms is immediately sent to him. But it is possible that a user never receives the email, or perhaps he is unable to locate the email that he might have received a few days back. Such a user would ask for the confirmation link to be sent again. This means that we need a mechanism for resending an email to a user. This tutorial explains the steps needed to generate and resend the link to that user.

Forgot Password functionality in Identity based Authentication

Very often a user is unable to remember the password that he created for a website. In such circumstances, the forgot password link comes to his rescue - it is one of the most important links on a login form. And, in this tutorial we shall implement the functionality for a forgot password link. Let's proceed!

Reset Password functionality in Identity based Authentication

We have seen in the previous tutorial that when a user fills the forgot password form, then he is emailed a link to the reset password page. The link contains a password reset code. Now, in this tutorial we shall add a page for reset password.

Claim based Authorization with Identity

In its simplest terms, a claim is a name-value pair used to verify authorization. For example, you may be authorized to access a page if a claim of name "my_role" and of value "admin" is attached to your identity. In this tutorial we learn how to configure a project for claim based authorization, and how to add claim based authorization to a page.

Layout Pages and LoginPartial for Identity

It is a good idea to show the user name of a logged user in the header of each page of a website. And, if the user is not logged in, then the login and register buttons can be shown instead. The best way to implement it is to use partial views in combination with layout pages. This tutorial explains the steps for this.

Sign out functionality in Identity based Authentication

A sign out link allows a logged user to log out of your website. It is usually shown in the header of a page and close to the name of the logged in user. In this tutorial we shall learn how to implement this functionality.

Account Lockout Functionality in Identity

You must have seen on various websites that a user account gets locked if the user makes about three unsuccessful login attempts. The exact same functionality is supported by the Identity API also - and it is possible to configure the number of failed attempts before an account gets locked. If a lockout timespan is specified, then the account remains locked for that specific duration. The default value is 5 minutes, but it can be set to any value. The number of failed attempts and the clock are reset when a user performs a successful login.

Enabling 2-factor Authentication in Identity

Two factor authentication gives additional security to a login process. But this type of authentication has to be specifically enabled by a user. For this he clicks a button to receive an authentication code or token. This token is provided by the asp.net core app. After that he installs an authenticator app from Microsoft, or from Google or from IOS Play Stores. Then he has to enter that authentication code into the authenticator app and receive a code from that app. This code is then entered into the asp.net core application, and the two factor authentication gets enabled. In this tutorial we shall add a razor page to enable two factor authentication.

Login with 2-Factor Authentication

Consider a user who has enabled 2-factor authentication as explained in the previous tutorial. Such a user is required to authenticate twice before he can access the pages of a website. The first authentication is through the common login page, and then immediately after that he is redirected to a second login page where he has to enter a validation code obtained from his Google, Microsoft or IOS authenticator app. The purpose of this tutorial is to complete the second login page - also called 2-factor login page.

Disabling 2-Factor Authentication

The purpose of this tutorial is to add the functionality that allows a user to disable his 2-factor authentication. For this we shall have to modify the _LoginPartial page so that the disable 2-factor authentication link is shown to him.

Creating a Google OAuth App for Authentication

Social media based authentication requires us to create an oauth app on a social media platform such as google, facebook, twitter, github. This app provides us a client id and a client secret key for use in various classes that provide social media integration. In this tutorial we have a walkthrough for creating an oauth app on the google cloud console. Steps for other social media are similar - so you can take them as an exercise.

Social Media based Authentication, Remember Me and Signout

Social media based login provides a neat and user-friendly means of logging into your website. Users are more likely to trust this method because of the level of security provided by various social media platforms. It helps us simplify the sign-in process by delegating many complexities to social media platforms. In this tutorial we present a project that requires a user to login with his google account. Once he logs in, then he is shown his email-id, name and profile picture. We also explain persistence of cookie, i.e., how the user can be remembered, and also the signout scheme.


☞FIND A DOCTOR PROJECT - Step 7

Now we start completing a doctor's profile. Three modules are done - (1) first the doctor's name, phone and photo upload, (2) second the fees he charges, and (3) a dropdown of specializations. A partial view is added for specializations because specializations will be used from the patient side also, during the search of doctors.


☞Ch9 - AJAX COMMUNICATION

Ajax based POST of a Razor Page

How to POST an ASP.NET Core Razor FORM through an Ajax Request. We discuss a practical approach that is to-the-point and easy to understand. The given code is ready to copy-paste!

How to POST data with AJAX Independently

Anti-forgery token is NOT available outside of <form> tags. This article, alongwith the appended  video, explains how to use IAntiforgery service to solve this limitation, and POST data, especially as an AJAX request, when a full-fledged form is not possible?

Bare minimum code for a parameterized AJAX GET Request to a C# function

The following project has a textbox with a send button. The click event fires an AJAX GET request and sends a string parameter to an ASP.NET Core application, which responds by converting the parameter to its uppercase equivalent. The client side script has been written using pure javascript.

Admin Panel with Content on the Right

This project is about creating an Admin Panel that would be suitable for a reporting project or an EBook that shows a table of links on the left and the corresponding content on the right side. The content is obtained by an Ajax call to an ASP.NET Core application. Source code for all the three files has been given and explained below.

Authentication and Authorization with AJAX Requests

In brief: Just two additions are required to implement AJAX based authorization in your existing ASP.NET Core application - first is on the javascript side - where the response code should be tested, and second on the server side where User.IsInRole has to be tested. The concept is explained in the text that follows, and a working example is described in the appended youtube video!

Inline, In-place Edit, Update, Cancel of records without a page refresh

Simplest explanation of AJAX based Edit, Update, Cancel operations on a row of an HTML table. An ASP.NET Core POST handler receives the updated values that can be processed for an update to a database.

Master Slave Cascading Dropdowns with Ajax

In nutshell: The selection change event of the master dropdown is used to send the "id" of the selected item to the server, which sends back a collection of items for the slave dropdown. A javascript based Ajax GET request is used for this communication with the server.


☞FIND A DOCTOR PROJECT - Step 8

Cascading dropdowns and ajax are used for completing the fourth module of a doctor's profile where the state and city of the clinic address have to be specified. For this we have added a partial view _ClinicAreaPIN to render the cascading dropdowns. A partial view has been added because a patient will also need these dropdowns during his search for a doctor. A JSON based database is used to store the State-City data.


☞CORS HANDLING with ASPNET CORE (can skip for later)

How Cross Origin requests (CORS) fail - example with ajax javascript

We shall run two ASPNET Core apps concurrently - the first exposes a web API, whereas the other shows a web page containing two links - the first of these links causes a direct call to the web API, and the second fires an ajax based call through javascript. A direct call is not a cross-origin (CORS) call because its destination is visible in the browser, but a call that occurs through an invocation of XMLHttpRequest or fetch API is a cross-origin (CORS) call. We shall verify that a click on the first link succeeds, but the second link fails because a browser blocks cross-origin calls.

Why cross-origin requests (CORS) fail and why they succeed?

In the previous tutorial, we demonstrated how a browser blocks cross-origin calls. So you must surely be wondering why cross-origin requests to CDN-hosted CSS files and fonts succeed. What's behind that success? Why do browsers permit some requests and block others? In this tutorial, we examine the reasons behind this. It will help us allow cross-origin requests in our ASPNET Core apps!

Enabling CORS with a Policy

An ASPNET Core application can permit cross-origin requests by adding "Access-Control-Allow-Origin" header to the HTTP response. Cross-origin requests are not allowed by default; they must be allowed explicitly. One way of doing it is by defining a suitable policy in the application pipeline. In this tutorial, we learn the steps required for this. We shall also learn how to define multiple policies so that each end-point can serve requests to its own set of origins.

Enabling CORS for Specific CSS or JS Files

Static files are NOT accessible cross-origin if we call UseStaticFiles before UseCors. But if we reverse the order, every static file becomes accessible to permitted origins. So we have an all-or-none type of situation. CORS can either be disabled for every static file or disabled for none. This tutorial explains how to enable CORS for just a small subset of files, as done by the various CDN networks.

Primer on CORS Preflight Requests

Browsers consider some cross-origin requests as unsafe. For example, an HTTP PUT request is considered unsafe. A browser first queries the server if it accepts that type of verb or request or headers by sending an HTTP OPTIONS request, which is called a preflight request. In this tutorial, we learn some concepts regarding preflight requests.

Configuring CORS Preflight Policy

In this tutorial, we learn how to set a CORS policy that will respond to a pre-flight OPTIONS request. This policy will specify the list of acceptable request headers, a list of acceptable HTTP methods and a duration value for the Access-Control-Max-Age header.

Credential Cookies with Cross-Origin Requests

By default, a browser doesn't send authentication cookies with cross-origin requests. It sends cookies only if the javascript code sets a property called "credentials" to true or "include." But that's not the whole story. The server-side code must also set an "AllowCredentials" cross-origin policy so that it can respond with a header called "Access-Control-Allow-Credentials." If the browser doesn't receive this header, it logs a cross-origin failure even if the origin is white-listed on the server. Thus, it is a matter of writing the javascript code correctly, and configuring the cross-origin policy that signals the browser that cross-origin cookies are allowed. This polocy will not work if wild-cards are used in the "WithOrigins" function, or "AllowAnyOrigin" function has been used.

Practical Verification of Credential Cookies

In this tutorial, we have two applications - the first is an ASPNET Core application that implements a CORS policy to accept cookies from the second application. The second application makes a javascript request to the first application and sends a cookie. The first application then reads the cookie and echoes back the contents of that cookie, which are presented by the browser through a javascript alert box. The source code of both the projects is provided in the attached downloads.


☞Ch 10 - UNDERSTANDING LINQ QUERIES

SingleOrDefault, Find, FirstOrDefault, Single and First

This is an explanation of SingleOrDefault, FirstOrDefault and Find methods from a practical point of view. We have explained when to use which one and how to use. We have also explained how Single is different from First, and how Single is different from SingleOrDefault, and also how First is different from FirstOrDefault.

Where, Include and ToList

This is an explanation of Where, Include and the ToList methods from a practical point of view. We have explained when to use which one and how to use. We have also explained how a SQL JOIN can be performed by using the "Include" function of EF Core.

How to Sort Records

A result set can be sorted in ascending as well as descending order. It is even possible to perform a chained sorting by using "ThenBy" and "ThenByDescending" methods. Finally we discuss whether "OrderBy" should be before or after "Where".

Direct Execution of SQL Queries and Stored Procedures

EF Core translates your LINQ expressions into SQL language queries. However, sometimes it is easier, convenient and faster (as determined by testing) to run queries directly on a database. This tutorial explains how to run SELECT, UPDATE, INSERT, DELETE and execute Stored Procedures and obtain the resultset directly.


☞FIND A DOCTOR PROJECT - Step 9

Partial pages for _Consultation and _Consultations are added for creating/editing a consultation and viewing all the consultations. Then razor pages for Consultation are added to both the doctor and patient. The home pages of doctor and patient are also updated to show all the consultations.

The patient profile module is also completed now.


☞Ch 11 - DATABASE CONNECTIVITY - III

Status of the App_Data folder in ASP.NET Core and what is the way forward?

Looking for the "protected" App_Data folder in ASP.NET Core? The news is that it doesn't have that status anymore. It is no longer a "Special" folder. However, a workaround exists, and I demonstrate it in this tutorial. This tutorial explains how to read the contents of a notepad file (located in a "protected" folder of any random name). The contents are read from within the application, and displayed. Later we verify that the same notepad file cannot be accessed from the browser. This concept can easily be extended to use XML as a database, a topic we shall explore in some future posts.

How to use XML as a database in ASP.NET Core

This is the simplest example of reading and updating a record. For simplicity, the record consists of just one property called Name. An input textbox is used to display the "Name" and the same textbox is used to post the updated value. Reading and writing is done with the built-in XMLSerializer class.

Repository Pattern and Dependency Injection with XML as Database

This is a walkthrough on how to make calls to an XML database via repository pattern and dependency injection. We also give a brief introduction to the repository pattern and dependency injection, and also explain the associated benefits.

MySQL Database Connectivity in an ASP.NET Core Razor Page Project

These are the minimal steps for connecting to a MySQL database server with EF Core. A simple application of one textbox form has been used to demonstrate how records can be inserted into a table in a MySQL database. The tables and database are created automatically by EF Core on the basis of code first approach.

SQL Server Database Connectivity in an ASP.NET Core Razor Page Project

These are the minimal steps for connecting to a Microsoft SQL Server database with EF Core. A simple application of one textbox form has been used to demonstrate how records can be inserted into a table in a SQL Server database. The tables and database are created automatically by EF Core on the basis of code first approach.


☞Ch11A - EF CORE BEST PRACTICES AND PERFORMANCE

Set a SQL Server Project

In this tutorial we shall set a project to use SQL Server as our database. You can obtain this project from the downloads attached to this video. But still I recommend that you go through this tutorial to ensure that everything is setup correctly on your specific machine. You might have to substitute your own connection string.

Identify Slow Commands with Logging and Tags

EF Core provides logs that help us determine the time taken by a specific query to finish. The logs also display the actual SQL query that was executed on the database end. This means that we have a very transparent way of knowing the actual command in SQL syntax, and also about the time it took for completion. Hence we can diagnose queries that execute too slow - possibly because an index was missing on the database. In this tutorial we also examine how to use tags with logs.

Comparison of Select, Projection, Tracking and Execution in Database

We shall use various methods to calulate the sum of prices of all the records in the items table. We will also take note of the times taken. Usually the best results are obtained if tracking is disabled for readonly queries and if SELECT is limited to just the columns needed and, if possible, by allowing the calculations to take place in the database. But keep in mind that each query has its own circumstances. So NEVER ASSUME RESULTS. TEST, TEST and TEST is the best way to determine the optimal query in each case.

Lazy Loading and the n+1 problem

Lazy loading is a great O/RM pattern that AUTOMATICALLY loads dependent (child) data when it is first accessed. The delayed loading is both an advantage and a disadvantage. This tutorial explains both these aspects and the associated pitfalls. EF Core doesn't enable lazy loading by default.

Buffering and Streaming of Resultset

A query can first store the entire resultset into memory, and then use a foreach loop to process each item. Alternatively, it can stream each result into a foreach loop one by one. We examine both these possibilities in this tutorial.

Raw SQL with FromSqlRaw for Efficiency

Suppose your database team have already provided you an optimized query in SQL syntax. Or let's say you have a legacy, old setup that makes it compulsory to run a query in raw SQL syntax. In such cases you can use the FromSqlRaw extension to make that call.

Stored Procedures and Secure Parameterization to Prevent SQL Injection attacks

Raw SQL queries and Stored Procedures can be executed with the FromSqlRaw extension. It is very common that these queries and procedures require parameters on the basis of values provided by a user. User-provided parameters are often a source of sql injection attacks. In this tutorial we learn how to pass parameters in a safe manner.

Batching in EF Core and Planning your Bulk Updates

EF Core uses batching to execute bulk updates in a single trip to the database. You can always fine-tune your code by carefully sequencing your statements so that ef core can batch them up. In the second part of this article we have a walkthrough to analyze a piece of code that triggers various trips to the database server, and we explain how that same code can be simplified and optimized to one single trip.


☞Ch12 - DOCKER CONTAINERIZATION (can skip for later)

What is Docker, Dockerfile, DockerImage and Containerization?

This article is a beginner's introduction to the terminology associated with docker files, docker images and containers. I have kept the explanation bare simple so that it's easy to get started. I have tried to explain the most basic questions like what is a docker, what is it's use for you, and what the basic terms mean in nutshell.

How to Create a Docker Image with Visual Studio

This is a walkthrough on creating a docker image with visual studio. We start by creating a simple asp.net core project with sqlite database connectivity, and then explain how Dockerfile can be easily created, followed by a docker image. We have included database connectivity because we shall use the same project for persistence with docker volumes later on.

How to run a Docker Image with Docker Desktop

This is a walkthrough on running a docker image. We start by explaining the commands for listing the docker images on a computer. Then we explain the commands for running a docker image, and for gracefully shutting down the container. Finally, we examine that when the images are run in this manner, the data is not persisted to disk.

How to use Docker Volumes to Persist Data

In the previous tutorial we were able to run an image in a docker container. The docker container provided a RW memory for our project and also for our sqlite database file. And, we noticed that although the app was running fine, yet the data was not persisting between restarts of the container - it was not getting commited to a persistent store. Whenever we closed and restarted the app we found that the sqlite database started blank, with no data. In this tutorial we shall learn how to attach a virtual disk (or a volume) to your container so that data can persist on your hard disk, so that the data remains available on the next start of the container.

How to Publish a Docker Image to DockerHub Registry with Visual Studio

This is a walkthrough on uploading a docker image to the docker hub registry. We shall upload the same hellodocker project and then verify the uploaded image by visiting the docker hub portal.

How to Pull and run MS SQL Server Image in Docker Desktop

In this tutorial we shall learn how to pull and run the docker image of Microsoft SQL Server through the Docker Desktop program. In this same tutorial we shall establish a connection to this instance with the Visual Studio SQL Server Object Explorer.

Connectivity to SQL Server Running in a Docker Container

In this tutorial we shall learn how to connect an ASP.NET Core application to a SQL Server image that is running inside a docker container. Some data is entered and later verified that the data indeed reached the SQL Server Instance.


☞Ch13 - DATABASE MIGRATIONS

What are Database Migrations, Configuring Visual Studio for Database Migration, Getting Started with your first EF Core Migration, Migration on Alterations to a Model, SQL Scripts for Migration

Who this course is for:

Course Details:

  • 26.5 hours on-demand video
  • 168 downloadable resources
  • Full lifetime access
  • Access on mobile and TV
  • Certificate of completion

C# ASP.NET Core 7 + MVC, Razor Pages + Exercises + Projects udemy free download

ASP.NET Core is not difficult! My Projects of 7/8 steps are more than sufficient for a quick and practical transition!

Demo Link: https://www.udemy.com/course/h-asp-core/