Notes on C#, ASP.NET Core and .NET Core web dev platform

Last updated on 9 Dec. 2024

A web dev. project that I am starting to study, uses ".Net Core" for the back-end and ReactJS for the front-end. I want to get a quick overview of .Net Core and am doing some reading/viewing on it in short bursts. Notes about it are given below.

ASP.NET Core, https://dotnet.microsoft.com/en-us/apps/aspnet seems to be the main official docs page. Some key points from it:
  • Free. Cross-platform. Open source.
  • A framework for building web apps and services with .NET and C#.
  • Supported on Windows, Linux, and macOS
Hmm. That's quite interesting. My last industry project, IIRC, was on ASP.NET and C# in 2002. I don't think it was free then, nor cross-platform (I think it was only Windows platform then) and not open source. Quite fascinating that 22 years later, the name of the web dev. platform has not changed much - from ASP.NET to ASP.NET Core and the language is still C#. Of course, the features of ASP.NET Core as well as C# today will be far more than what it was 22 years back.

It seems to be a 'one' stack (it also uses 'full' stack term) dev. platform where the front-end and back-end can be developed.

It claims to be fast and scalable and faster than Node.js or Java Servlet.

It claims to be secure and offers "built-in user database with support for multi-factor authentication and external authentication with Google, X, and more".

It claims to have an active community (and its source code is on GitHub).

"Get 10 ASP.NET Core websites for free with Microsoft Azure." Hmm. That's nice!

It offers free ebooks on Blazor, .NET Core architecture and Azure.


Overall, I am quite impressed with the claims on this page. Through these technologies, Microsoft may be providing a one-stop solution for small to medium scale enterprises for web app development. In early 2000s, if I recall correctly, Microsoft's ASP.NET was OK for small to medium scale projects but for large projects, J2EE (Jave 2 Enterprise edition) was preferred.

=======================

ASP.NET Core Crash Course - C# App in One Hour, https://youtu.be/BfEjDD8mWYg - Seen most of it and plan to see remaining part in near future. Seems to give a decent quick look at creating very simple web app. with back-end database, using ASP.NET Core.

=========================

From my log of 2 Nov. 2024

I am trying it with .Net 6.0 (Long Term Support) as I don't have .Net 8.0 (Long Term Support)
Using NuGet for 'Microsoft.EntityFrameworkCore.InMemory' failed with error message:\Severity Code Description Project File Line Suppression State
Error NU1202 Package Microsoft.EntityFrameworkCore.InMemory 8.0.10 is not compatible with net6.0 (.NETCoreApp,Version=v6.0). Package Microsoft.EntityFrameworkCore.InMemory 8.0.10 supports: net8.0 (.NETCoreApp,Version=v8.0) TodoApi ...\source\repos\TodoApi\TodoApi.csproj 1
-----------

So I need to install/upgrade to .Net 8.0.


For that I need to update Visual Studio 2022 to 17.8+ (mine currently, IFIRC, is 17.7).

VS Installer on my PC said that I have to "Resume" my paused Setup! The Update button was not shown. So I first clicked on "Resume". That seems to first update VS Installer.
Once that got done, it moved to next step of downloading 1.96 GB! (Perhaps VS 2022).

After some amount of download of above 1.96 GB (don't know how much), an error was shown along with a message about low-bandwidth install (I think this is related page for that: Create an offline installation package of Visual Studio for local installation, https://learn.microsoft.com/en-us/visualstudio/install/create-an-offline-installation-of-visual-studio?view=vs-2022).

Acknowledging the error took me back to main window where Update was now available. So I clicked on Update to essentially retry the install. Now it is downloading 4.44 GB!

I got to the stage of "Downloaded" (all of the install was downloaded, I presume). I used all of Airtel and Jio daily data, used a bonus 2 GB pack on Airtel (100 MB left it says), and used a 2 GB data addon on Jio (675 MB remaining it says). [All this was done on 2 Nov. 2024]

Now it is installing (83%).

Installation got done - version installed is 17.11.5 [Around 11.30 PM on 2 Nov. 2024]

Launched VS Studio 2022, confirmed that is above version number. Then tried to pick up tutorial program creation (Tutorial: Create a web API with ASP.NET Core, https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-8.0&tabs=visual-studio) from where it had failed. But it failed again. Probably due to project creation using .Net 6.0.

Created a new project for the tutorial, confirmed that it is using .Net 8.0, and this time the step of Using NuGet for 'Microsoft.EntityFrameworkCore.InMemory' succeeded.
I could build and run the wizard created API successfully. I could also test the API with Swagger (generated by wizard) and directly on browser with the API working as expected. [11.57 PM, 2 Nov. 2024]

============================

As the .NET Core API wizard created program I am going through uses C#, I have to do some catching up with C# language features as it is now.

C# Tutorial, https://www.w3schools.com/cs/index.php served as a good refresher of what I already knew of C#. I think it had limited or no additional coverage of C# features that are newer (like lamba expression or LINQ).

Roadmap for JavaScript and TypeScript developers learning C#, https://learn.microsoft.com/en-us/dotnet/csharp/tour-of-csharp/tips-for-javascript-developers was very useful to understand new features of C# in the context of what I know in JavaScript and TypeScript. Two of new features related overview articles seem to be very useful:

As needed, I can dig deeper into above articles and references it provides.
===========================
3 to 7 Nov. 2024

3 Nov. 2024
The above tutorial is for a "controller-based web API".

A simpler API is a "Minimal API". See: Tutorial: Create a minimal API with ASP.NET Core, https://learn.microsoft.com/en-us/aspnet/core/tutorials/min-web-api?view=aspnetcore-8.0&tabs=visual-studio

Choose between controller-based APIs and minimal APIs, https://learn.microsoft.com/en-us/aspnet/core/fundamentals/apis?view=aspnetcore-8.0

I think it is wiser for me to first go through the Minimal API tutorial.
Created a soln: MinTodoApi as per tutorial. The 'Hello world' app. the wizard creates is super-simple (4 lines of code excluding blank lines in the main code file: Program.cs) but functional:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
----

Had a quick look at: Quickstart: Deploy an ASP.NET web app, https://learn.microsoft.com/en-us/azure/app-service/quickstart-dotnetcore?tabs=net80&pivots=development-environment-vs ... Seems quite easy. Plan to try it out sometime.

----

Was able to try out the minimal API tutorial (above) till "Use the TypedResults API", https://learn.microsoft.com/en-us/aspnet/core/tutorials/min-web-api?view=aspnetcore-8.0&tabs=visual-studio#use-the-typedresults-api . I think I need to take a break and get a better understanding of the code so far before going to TypedResults API part.

Entity Framework (EF) Core is a lightweight, extensible, open source and cross-platform version of the popular Entity Framework data access technology.

EF Core can serve as an object-relational mapper (O/RM), which:

Enables .NET developers to work with a database using .NET objects.
Eliminates the need for most of the data-access code that typically needs to be written.
--------


In this tutorial, you create a .NET Core console app that performs data access against a SQLite database using Entity Framework Core.
-----
Tutorial: Learn to manage data collections using the generic list type, https://learn.microsoft.com/en-us/dotnet/csharp/tour-of-csharp/tutorials/list-collection

Constructor invocation expressions are target-typed. That is, if a target type of an expression is known, you can omit a type name, as the following example shows:
List<int> xs = new();
----

SQLite Viewer Web App, https://sqliteviewer.app/

==============================================

A nullable value type T? represents all values of its underlying value type T and an additional null value. For example, you can assign any of the following three values to a bool? variable: true, false, or null.
...
int m2 = 10;
int? m = m2;
---

Enumerable.ToArray<TSource>(IEnumerable<TSource>) Method, https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.toarray?view=net-8.0 :
Creates an array from a IEnumerable<T>.
----



With EntityFramework, you create an object-relational mapping between C# classes and your database schema. You write your queries against the objects, and at run-time EntityFramework handles the communication with the database. In the following example, Customers represents a specific table in the database, and the type of the query result, IQueryable<T>, derives from IEnumerable<T>.

Northwnd db = new Northwnd(@"c:\northwnd.mdf");

// Query for customers in London.
IQueryable<Customer> custQuery =
    from cust in db.Customers
    where cust.City == "London"
    select cust;
==========


A record in C# is a class or struct that provides special syntax and behavior for working with data models.
...
For records, value equality means that two variables of a record type are equal if the types match and all property and field values compare equal. For other reference types such as classes, equality means reference equality by default, unless value equality was implemented. That is, two variables of a class type are equal if they refer to the same object. Methods and operators that determine equality of two record instances use value equality.

Not all data models work well with value equality. For example, Entity Framework Core depends on reference equality to ensure that it uses only one instance of an entity type for what is conceptually one entity. For this reason, record types aren't appropriate for use as entity types in Entity Framework Core.

...

public record Person(string FirstName, string LastName);

public static class Program
{
    public static void Main()
    {
        Person person = new("Nancy", "Davolio");
        Console.WriteLine(person);
        // output: Person { FirstName = Nancy, LastName = Davolio }
    }

}
=============

Write C# LINQ queries to query data, https://learn.microsoft.com/en-us/dotnet/csharp/linq/get-started/write-linq-queries - seems to be a good intro. It covers query expressions (query syntax), method-based queries (method syntax) and lambda expressions in (method-based) queries.
 

=============================

11 Nov. 2024


Should I use EF6 or EF Core?, https://learn.microsoft.com/en-us/ef/ef6/#should-i-use-ef6-or-ef-core : "EF Core is a more modern, lightweight and extensible version of Entity Framework that has very similar capabilities and benefits to EF6. EF Core is a complete rewrite and contains many new features not available in EF6, although it also still lacks some of the most advanced mapping capabilities of EF6."

Code First to a New Database, https://learn.microsoft.com/en-us/ef/ef6/modeling/code-first/workflows/new-database : The around 10 min. video linked in the article is good but somewhat terse.

The first video in this series is good and somewhat easy-paced and covers defining a model, how a model maps to the database, creating the database using migrations, updating the database schema using migrations, adding, querying, updating and deleting data in the database: Getting Started with Entity Framework Core [1 of 5] | Entity Framework Core for Beginners, https://www.youtube.com/watch?v=SryQxUeChMc&list=PLdo4fOcmZ0oX7uTkjYwvCJDG2qhcSzwZ6, 15 min. 45 secs., by dotnet in Apr. 2022.

------------


Working With Transactions In EF Core, https://www.milanjovanovic.tech/blog/working-with-transactions-in-ef-core , Feb. 2023 by Milan Jovanović : "By default, all changes made in a single call to SaveChanges are applied in a transaction. If any of the changes fail, the entire transaction is rolled back and no changes are applied to the database. Only if all changes are successfully persisted to the database, the call to SaveChanges can complete."

ASP.NET Core Web API: Secure, Scalable, and Elegant, https://github.com/kawser2133/web-api-project , LU May 2024: "Explore a meticulously crafted ASP.NET Core Web API, featuring Security Identity, JWT, Unit Testing, and API Versioning. This repository embodies best coding practices, delivering a clean, efficient, and scalable solution. Feel free to ask any questions or share your thoughts."

Complete Guide to Asp.Net Core Web API, https://github.com/etrupja/complete-guide-to-aspnetcore-web-api , LU May 2021 : 'This is the source code of the "Complete Guide to Asp.Net Core Web API" course'.

Awesome collection of .NET Core realtime, sample, architecture reference application projects, https://github.com/bharatdwarkani/awesome-dotnet-core-applications , LU Jul. 2020 : "Open-source projects are great for getting started and serve as a good source for architecture reference. There are several open-source ASP.NET Core projects available in GitHub. These projects will help you learn ASP.NET Core technology in-depth, with different types of architecture and coding patterns."

============================


virtual (C# Reference), https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/virtual : "The virtual keyword is used to modify a method, property, indexer, or event declaration and allow for it to be overridden in a derived class."


is operator, https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/type-testing-and-cast#is-operator : "The is operator checks if the run-time type of an expression result is compatible with a given type. The is operator also tests an expression result against a pattern."


You use declaration and type patterns to check if the run-time type of an expression is compatible with a given type. With a declaration pattern, you can also declare a new local variable. When a declaration pattern matches an expression, that variable is assigned a converted expression result, as the following example shows:

object greeting = "Hello, World!";
if (greeting is string message)
{
    Console.WriteLine(message.ToLower());  // output: hello, world!
}
============


2nd video in series: Working with an Existing Database [2 of 5] | Entity Framework Core for Beginners, https://www.youtube.com/watch?v=DCYVfLT5_QI, 6 min. 1 sec. Covers "how to reverse engineer an existing database for use with EF Core". Also, IFIRC, quickly mentions two approaches to handle code changes due to schema changes.

3rd video in series: ASP.NET Core Web Apps with EF Core [3 of 5] | Entity Framework Core for Beginners, https://www.youtube.com/watch?v=c-wN-fc594c , 8 min. 46 secs. Covers how ASP.NET Core can use EF Core to quickly create a CRUD web app (front-end and back-end). The wizard seems to be doing lot of the code generation based on database model. It will be interesting to explore this in some detail from context of creating simple web apps quickly.

Database Providers [4 of 5] | Entity Framework Core for Beginners, https://www.youtube.com/watch?v=moRmKo3nrN4, 9 min. 7 secs. "EF Core works with many different database technologies. See us demonstrate the usage of the Sqlite, PostgreSQL, and Azure Cosmos DB providers." The database provider for the app. created in previous videos is first changed from Sql Server to Sqllite, and then PostgreSQL. The procedure involves adding appropriate provider NuGet package (and removing earlier one), minimal code changes to use new provider and appropriate connection string, and then migration. Quite impressive to see how easily the database provider could be changed for this app even though the app is very simple and its database schema seems to use features available across all these providers.
Finally Azure Cosmos DB NoSQL provider is used where the procedure changes significantly.

Performance Tips [5 of 5] | Entity Framework Core for Beginners, https://www.youtube.com/watch?v=jgESld7U5Bw , 6 min. 35 secs. Interesting but perhaps I can get into its details later on when needed.

How to code along with these videos [Supplemental] | Entity Framework Core for Beginners, https://www.youtube.com/watch?v=Qh42pe1Ae5U , 3 min. 49 secs.

--------------

Continued: Tutorial: Create a minimal API with ASP.NET Core, https://learn.microsoft.com/en-us/aspnet/core/tutorials/min-web-api?view=aspnetcore-8.0&tabs=visual-studio ... But looks like this part of the site has the tutorial and other guide-type pages: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis/overview?view=aspnetcore-8.0 . The pages available can be seen in the left pane. "WebApplication and WebApplicationBuilder", "Route Handlers" and "Create responses" are some these guide-pages which I found to be very useful to understand the tutorial code. Note that the tutorial page with the sample todo web API has a lot of code and tends to jump into the code without much explanation. This is where the guide-pages are very helpful - they have lot of explanations.
----

In the minimal api tutorial, we have following code in TodoDb.cs:
using Microsoft.EntityFrameworkCore;

class TodoDb : DbContext
{
    public TodoDb(DbContextOptions<TodoDb> options)
        : base(options) { }

    public DbSet<Todo> Todos => Set<Todo>();
}
---------

Set in above code seems to be invocation of Set method of DbContext class.

Set<TEntity>(), https://learn.microsoft.com/en-us/dotnet/api/system.data.entity.dbcontext.set?view=entity-framework-6.2.0#system-data-entity-dbcontext-set-1 : "Returns a DbSet<TEntity> instance for access to entities of the given type in the context and the underlying store."

In the code:
app.MapGet("/todoitems/{id}", async (int id, TodoDb db) =>
    await db.Todos.FindAsync(id)
        is Todo todo
            ? Results.Ok(todo)
            : Results.NotFound());
----
is Todo todo part of it seems to be a declaration and type pattern (see C# notes for more). If the earlier expression is a ToDo type then, as per my understanding, variable todo is created and initialized with expression result.

Results.Created(String, Object), https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.results.created?view=aspnetcore-9.0#microsoft-aspnetcore-http-results-created(system-string-system-object) : "Produces a Status201Created response." ... "Parameters" ... "The URI at which the content has been created." ... "The value to be included in the HTTP response body."

Results.Ok(Object), https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.results.ok?view=aspnetcore-9.0#microsoft-aspnetcore-http-results-ok(system-object) : "Produces a Status200OK response." ... "Parameters" ... "The value to be included in the HTTP response body."

12 Nov.: Was able to try out the minimal API tutorial (above) till "Use the TypedResults API", https://learn.microsoft.com/en-us/aspnet/core/tutorials/min-web-api?view=aspnetcore-8.0&tabs=visual-studio#use-the-typedresults-api . I now have a decent understanding of the minimal API tutorial code till "Use the TypedResults API". Next step is to proceed to TypedResults API part.
=======================

13 Nov.

The Task<TResult> class represents a single operation that returns a value and that usually executes asynchronously. Task<TResult> objects are one of the central components of the task-based asynchronous pattern first introduced in the .NET Framework 4. 
----

The Task Parallel Library (TPL) is based on the concept of a task, which represents an asynchronous operation. In some ways, a task resembles a thread or ThreadPool work item but at a higher level of abstraction. The term task parallelism refers to one or more independent tasks running concurrently.
----

A delegate is a type that represents references to methods with a particular parameter list and return type. When you instantiate a delegate, you can associate its instance with any method with a compatible signature and return type. You can invoke (or call) the method through the delegate instance.
----



The tuples feature provides concise syntax to group multiple data elements in a lightweight data structure. 
...
C# supports assignment between tuple types that satisfy both of the following conditions:

both tuple types have the same number of elements
for each tuple position, the type of the right-hand tuple element is the same as or implicitly convertible to the type of the corresponding left-hand tuple element

Tuple element values are assigned following the order of tuple elements. The names of tuple fields are ignored and not assigned, as the following example shows:
(int, double) t1 = (17, 3.14);
(double First, double Second) t2 = (0.0, 1.0);
t2 = t1;
Console.WriteLine($"{nameof(t2)}: {t2.First} and {t2.Second}");
// Output:
// t2: 17 and 3.14

(double A, double B) t3 = (2.0, 3.0);
t3 = t2;
Console.WriteLine($"{nameof(t3)}: {t3.A} and {t3.B}");
// Output:
// t3: 17 and 3.14
[--- end code ---]
You can also use the assignment operator = to deconstruct a tuple instance in separate variables.
...
var t = ("post office", 3.6);
var (destination, distance) = t;
Console.WriteLine($"Distance to {destination} is {distance} kilometers.");
// Output:
// Distance to post office is 3.6 kilometers.
[--- end code ---]
------------


A tuple provides a lightweight way to retrieve multiple values from a method call. But once you retrieve the tuple, you have to handle its individual elements. Working on an element-by-element basis is cumbersome, as the following example shows. The QueryCityData method returns a three-tuple, and each of its elements is assigned to a variable in a separate operation.

...

public static void Main()
{
    string city = "Raleigh";
    int population = 458880;
    double area = 144.8;

    (city, population, area) = QueryCityData("New York City");

    // Do something with the data.
}
==================

13 Nov.: Continuing with minimal API tutorial ...

TodoItemDTO.cs file:

public class TodoItemDTO
{
    public int Id { get; set; }
    public string? Name { get; set; }
    public bool IsComplete { get; set; }

    public TodoItemDTO() { }
    public TodoItemDTO(Todo todoItem) =>
    (Id, Name, IsComplete) = (todoItem.Id, todoItem.Name, todoItem.IsComplete);
}
---
In above file, the last statement: "(Id, Name, IsComplete) = (todoItem.Id, todoItem.Name, todoItem.IsComplete);" seems to be an example of tuples usage. See C# notes for more on tuples.

------
I now have a decent understanding of the whole minimal API tutorial.

=================
Interesting set of videos covering minimal web API from MSFT

Saw the entire set. From its description:
Web APIs are designed to enable applications to interact with data and business logic and exchange information with other services over common internet protocols like HTTP. This course introduces the basic concepts behind ASP.NET, including: the hosting model, middleware, and dependency injection. This course will also provide an overview of building HTTP-based services using minimal APIs.
----

I think the course is a good one and not too long - total playlist is slightly over an hour. The middleware and endpoint filters part cover topics not covered in above mentioned minimal API tutorial. Usage of endpoint filters for validation is very interesting. The example is a todo list but is quite different from minimal API tutorial's todo app.


================

https://learn.microsoft.com/en-us/aspnet/core/web-api/?view=aspnetcore-8.0 seems to have the same tutorial or similar as above, as one of the pages below it. It seems to be part of the main documentation of ASP.Net Core and has some related pages in the section (can be seen on left hand side panel).
==============
.Net 9.0 has been released recently. However, I am continuing with .Net 8.0 tutorial versions.

====================

Choosing Between Controllers and Minimal API for .NET APIs, https://www.c-sharpcorner.com/article/choosing-between-controllers-and-minimal-api-for-net-apis/ . This article concludes that controllers are good for "larger, complex projects" whereas minimal APIs are good for "smaller, more straightforward endeavours".

Controllers vs Minimal APIs, https://www.reddit.com/r/dotnet/comments/17t27cv/controllers_vs_minimal_apis/ . The comments in this post argue about minimal APIs being good only for simple projects or being good for more complex projects as well.

GH project mentioned earlier: ASP.NET Core Web API: Secure, Scalable, and Elegant, https://github.com/kawser2133/web-api-project , LU May 2024 - seems to be using controllers.

Another GH project mentioned earlier: Complete Guide to Asp.Net Core Web API, https://github.com/etrupja/complete-guide-to-aspnetcore-web-api , LU May 2021 - also seems to be using controllers.

So looks like my investing time in learning controllers based web API in ASP.NET Core could be helpful.

Web APIs for Beginners, https://www.youtube.com/playlist?list=PLdo4fOcmZ0oVjOKgzsWqdFVvzGL2_d72v is a playlist of 18 videos which covers building .Net Core Web APIs using controllers. I saw most of the 18 videos. The initial videos seem to have good explanations of the code and at a nice pace - not too slow and not too fast. But later videos seemed a little fast paced for me. 
I think it makes sense to first finish this set of videos and then go the web API controller tutorial page mentioned earlier as that page seems to have minimal explanation.

===================================

14 Nov. 2024

Now getting back to: [Controllers-based] Tutorial: Create a web API with ASP.NET Core, https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-9.0&tabs=visual-studio .

Last time (in period between 3 to 7 Nov), I think I had done only the first step of creating a "ASP.NET Core Web API" project template which creates a "WeatherForecast API with support for Swagger". 

I opened the solution and was able to get a rough idea of the template code now. Visual Studio's intellisense was very helpful in getting info. about methods invoked in the code. The code is not as easy to understand as the minimal API code. But I think that's fine as the controllers-based code seems to use a lot of features of ASP.NET Core (like attributes that have to specified in a particular way to get interpreted as wanted, Swagger through a package etc.) I think it may be a normal aspect of .NET programming using its framework, and am reminded of pre-2000s Windows desktop programs coded using MFC framework and associated wizards generating the starter-program (template) code. I think the sensible thing for me to do is to be satisfied with a rough idea of how the .NET web API related framework is being used, and dig into details as and when needed.

Now I plan to get to next step of changing the template code to the todo API as instructed in the tutorial page.

-----

The unary postfix ! operator is the null-forgiving, or null-suppression, operator. In an enabled nullable annotation context, you use the null-forgiving operator to suppress all nullable warnings for the preceding expression. 
-----

Visual Studio is taking just too long (perhaps around 20 mins now - my airtel mobile net conn. is slow giving perhaps around 1 Mbps average speed now around 9.30 PM but still this is taking just too long) for the "Scaffold a controller", https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-9.0&tabs=visual-studio#scaffold-a-controller step of the tutorial. The code does not seem to be hung as it seems to downloading stuff (NuGet Packages it seems - Microsoft.VisualStudio.Web.CodeGeneration.Design). ... I tried closing the window at which point it moved forward from Microsoft.VisualStudio.Web.CodeGeneration.Design to some other package! Then I got a dialog which said that a modal dialog seems to be active and provided me an option to continue with close or cancel. I chose cancel. Finally the scaffolding process got over! Perhaps it took around half an hour!

The resultant app seems to work as I tested Post and Get from Swagger and that worked as expected. The project folder size is around 52 MB. Did around 50 MB download take so long or did more stuff get downloaded and installed somewhere else? I guess I will know the answer only when I do this stuff multiple times in the course of further work I may do on controllers-based web APIs.

ASP.NET MVCScaffolding is very slow, https://stackoverflow.com/questions/10797597/asp-net-mvcscaffolding-is-very-slow, May 2012. : Don't know how relevant it is as it is a pretty old post. But it points to Windows Defender as the possible cause and gives some workarounds.

Controller scaffolding runs forever, https://developercommunity.visualstudio.com/t/controller-scaffolding-runs-forever-1/97570 , Aug. 2017 - The problem mentioned seems to be similar to what I faced. No proper solution is provided but a workaround is given: "If you kill the Visual studio instance sometimes it will work on second time of opening the project and repeating the process.".

--------

Article says, default location for global packages on Windows is: Windows: %userprofile%\.nuget\packages
On my PC, that is [User-name replaced by ...]: C:\Users\...\.nuget\packages .
The size of .nuget folder is 891 MB as of 15 Nov. 2024.
Command to list local folders: dotnet nuget locals all --list
Output of above command on running on my PC:
http-cache: C:\Users\...\AppData\Local\NuGet\v3-cache
global-packages: C:\Users\...\.nuget\packages\
temp: C:\Users\...\AppData\Local\Temp\NuGetScratch
plugins-cache: C:\Users\...\AppData\Local\NuGet\plugins-cache
--- end command output ---
The article has some info. on changing the location but it is not so clear. The following article seems to have more clear info. on it: How to change default Nuget packages folder on Windows, https://dev.to/tombohub/how-to-change-default-nuget-packages-folder-on-windows-51hb, May 2023. I plan to later on explore the ways to change location of these folders from C drive to D drive. 

======================


ASP.NET Core provides the following options for web API controller action return types:

Specific type
IActionResult
ActionResult<T>
HttpResults
=============


You use the yield statement in an iterator to provide the next value or signal the end of an iteration. The yield statement has the two following forms: ... yield return: to provide the next value in iteration ... yield break: to explicitly signal the end of iteration
---
The above page has simple examples of yield return and yield break.

C#: IEnumerable, yield return, and lazy evaluation, https://stackoverflow.blog/2022/06/15/c-ienumerable-yield-return-and-lazy-evaluation/ : Has good explanation of yield return with a simple example. Goes deeper into lazy evaluation feature of iterators.

The Journey of yield vs return in C#, https://osamadev.medium.com/the-journey-of-yield-vs-return-in-c-90ccd35df07c : Great article that gives a simple explanation of yield vs. return with an example program implemented using return and one using yield return, with the latter providing for lazy evaluation.

============================

Change Tracking in EF Core, https://learn.microsoft.com/en-us/ef/core/change-tracking/ is the first page of a set of pages covering Change Tracking in Entity Framework Core. - "Each DbContext instance tracks changes made to entities. These tracked entities in turn drive the changes to the database when SaveChanges is called.".. "This document presents an overview of Entity Framework Core (EF Core) change tracking and how it relates to queries and updates."

The Entry method can also be used on entities that are not yet tracked. This does not start tracking the entity; the state of the entity is still Detached. However, the returned EntityEntry can then be used to change the entity state, at which point the entity will become tracked in the given state. For example, the following code will start tracking a Blog instance as Added:

var newBlog = new Blog();
Debug.Assert(context.Entry(newBlog).State == EntityState.Detached);

context.Entry(newBlog).State = EntityState.Added;
Debug.Assert(context.Entry(newBlog).State == EntityState.Added);
-----------
Tutorial code [Controllers\TodoItemsController.cs]:
        public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
        {
            if (id != todoItem.Id)
            {
                return BadRequest();
            }

            _context.Entry(todoItem).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
            }
...
-------
So tutorial code uses the Entry method for updating an existing todoItem entry/row (entity instance).

======================

Now I have a rough understanding of the main controllers-based web API tutorial. The Data Transfer Object (DTO) model variant seems to be similar in approach to the DTO variant of minimal APIs tutorial which I had understood. So I am skipping the DTO model part of the controllers-based web API tutorial. That brings me to the end of this tutorial.

Very interestingly, an HTML/CSS/JS front-end seems to be provided for using the above web API! - Tutorial: Call an ASP.NET Core web API with JavaScript, https://learn.microsoft.com/en-us/aspnet/core/tutorials/web-api-javascript?view=aspnetcore-8.0

I followed the instructions in above page and was able to set up and run the HTML/CSS/JS front-end app. with the web API backend! As of now, I have not gone through the front-end code. Later on, if needed, I may do it.

UseStaticFiles(IApplicationBuilder), https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.staticfileextensions.usestaticfiles?view=aspnetcore-8.0#microsoft-aspnetcore-builder-staticfileextensions-usestaticfiles(microsoft-aspnetcore-builder-iapplicationbuilder) : "Enables static file serving for the current request path" ... "Files are served from the path specified in WebRootPath or WebRootFileProvider which defaults to the 'wwwroot' subfolder."

UseDefaultFiles(IApplicationBuilder), https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.defaultfilesextensions.usedefaultfiles?view=aspnetcore-8.0#microsoft-aspnetcore-builder-defaultfilesextensions-usedefaultfiles(microsoft-aspnetcore-builder-iapplicationbuilder) : "Enables default file mapping on the current path" ... "Files are served from the path specified in WebRootPath or WebRootFileProvider which defaults to the 'wwwroot' subfolder."

======================
Now am trying out publishing to Azure: Quickstart: Deploy an ASP.NET web app, https://learn.microsoft.com/en-us/azure/app-service/quickstart-dotnetcore?tabs=net80&pivots=development-environment-vs 

I had to create an Azure account which was complicated as it needed card info. Eventually it got created.
As I went through process to publish the app. (slightly different for the front-end+API app created earlier; above page has instructions for new app creation and then publishing it to Azure), I got the message that some more components (around 250 MB or so) need to be installed. So am doing that now (something related to Azure, IFIRC).
I had to retry publish. I selected 'Azure App Service (Windows)'. The App. Service dialog took a little time to show Subscription Name as "Free Trial".

In the hosting plan, I chose "free". By default it was S1 something. Note that I saw a message earlier that I have got some free credits but I don't know enough of this stuff now. So I want to play safe and so chose "free". The default location was Canada Central. I did not change it.

I chose 'Skip' for API Management dialog. That showed me Finish button which I clicked.
I got a message: "SuccessPublish profile 'D:\Users\...\source\repos\TodoApi\Properties\PublishProfiles\TodoApi-ravi - Web Deploy.pubxml' created.". I clicked on Close.
That took me to a 'Ready to publish' message with details of settings and Publish button on top-right.
I clicked Publish button ... It is taking quite some time to publish. It seems to be uploading lot of files (dll files mostly). Perhaps 10 to 15 minutes already and it has not finished yet.
Don't know whether free service is the cause for it to take so long.

It gave a message of retrying something. I think I have crossed half an hour now. Just too long. Note that this was being done late at night at which time usually the average Internet speed on my mobile connection is at least 5 to 10 Mbps.
...

----
1st link below points to 2nd which gives some PowerShell script as a solution. But it has to be run as admin and fiddles with certificates. I think it may be too tricky to try.
-----

I cancelled and retried and the publish got done in around 3 minutes!
I could access it both from desktop and mobile. Hmm. So my first Azure front-end plus web API full stack app is running.

The API is accessible at: https://todoapi-ravi.azurewebsites.net/api/TodoItems. This was at late night 15 Nov./early morning 16 Nov.

=========
16 Nov. 2024


Azure free account
Best for proof of concept and exploring capabilities

Available only to new Azure customers

Free monthly amounts of 25+ popular services for 12 months (new Azure customers only)

Free monthly amounts of 55+ always-free services

Access to full catalog of services up to free amounts and USD 200 credit

Spending protection—credit card won’t be charged*

No upfront commitment—cancel anytime

Move to pay-as-you-go pricing to continue beyond 30 days or after credit is used up
USD 200 credit
to use on Azure services within 30 days
===============================
From email "Welcome to your Azure free account", 10.37 PM, 15 Nov. 2024 from Microsoft Azure <azure-noreply@microsoft.com> to me:
Welcome to Azure, Ravi
Build your next idea with 12 months of free services and a USD200* credit. Start working in Azure now, with documentation that includes sample code, tutorials, quickstarts, and how-to guides.
===========================

The picture about Azure free trial is not clear. I think I will have free access for 30 days after which I have to switch to "Pay as you go" but there too I may get some set of free services and so not pay anything. But in "Pay as you go", I think there is a danger that inadvertently I might use some paid service and so get charged.

In Free trial, the feature of "Spending protection—credit card won’t be charged*" is listed which is not listed in "Pay as you go". So I think while in 30 day period of Free trial, I am protected against inadvertent use of paid service.

===========================
17 Nov. 2024 Update

How to use Git with Visual Studio 2022 (Step by step), https://www.youtube.com/watch?v=8zSVvTQXSIc , 15 min. 10 secs., Nov. 2021. Saw initial part of it. May be useful to view fully to see how Visual Studio 2022's Git commands work. As of now, I think I will mainly use command line git commands through Visual Studio Terminal as that's how I was doing it in VSCode.

Created public repo https://github.com/ravisiyer/DotNetTodoAPI for controllers-based web API.

=================
Created a new project similar to above TodoAPI but using MySQL local database instead of InMemory EF core package. Named project TodoAPISQL. After creating a new web API project, I copied appropriate files from TodoAPI project to TodoAPISQL. I had to then change some namespace entries. IFIRC, I first ran the project with InMemory EF Core and that worked. Next step was to move from InMemory EF Core to suitable MySQL EF Core package. That turned out to be a longish step involving lot of exploration and trial-and-error which can be seen in the following notes.

MySql.Data 9.1.0, https://www.nuget.org/packages/mysql.data/ : "MySQL provides connectivity for client applications developed in .NET compatible programming languages with MySQL Connector/NET through a series of packages." Has example code that creates SQL commands and executes it. E.g.:
      myCommand.CommandText = @"SELECT * FROM clients WHERE client_id = @clientId;";
      myCommand.Parameters.AddWithValue("@clientId", clientId);
-----

MySql.EntityFrameworkCore 8.0.8, https://www.nuget.org/packages/MySql.EntityFrameworkCore/8.0.8 : "MySQL provides connectivity for client applications developed in .NET compatible programming languages with MySQL Connector/NET through a series of packages.

MySql.EntityFrameworkCore adds support for Microsoft Entity Framework Core (EF Core) 6, 7, 8 and 9."

Looks like MySql.EntityFrameworkCore 8.0.8 is the key package to be installed for using MySQL through Entity Framework. It seems to use (have a dependency on) MySql.Data.

MySQL Connector/NET Developer Guide, https://dev.mysql.com/doc/connector-net/en/ "This manual describes how to install and configure MySQL Connector/NET, the connector that enables .NET applications to communicate with MySQL servers, and how to use it to develop database applications." The following part of above guide seems to be the relevant one for EFCore:
7.2 Entity Framework Core Support, https://dev.mysql.com/doc/connector-net/en/connector-net-entityframework-core.html . It specifically mentions "MySql.EntityFrameworkCore" package.

https://www.nuget.org/profiles/MySQL lists MySql.Data and MySql.EntityFrameworkCore as the first two packages. It then lists MySql.Data.EntityFrameworkCore but also says it is deprecated. There is a MySql.Data.EntityFramework package too but that seems to be for earlier versions of .Net Framework (4.6.2).

So the bottom line in all this version confusion seems to be, for my needs, the two key packages are: MySql.Data and MySql.EntityFrameworkCore.

=========

I Went from Zero to Hero with Entity Framework and MySql!, https://www.youtube.com/watch?v=SdtOGowW-Dk , 15 min. 30 secs., Jun. 2023. Saw whole of the video. Its a good intro. Seems useful except that it uses some Pomelo something MySQL package instead of the ones mentioned above.
----


Got the TodoAPISQL program build successfully. Used variation of following code from https://dev.mysql.com/doc/connector-net/en/connector-net-entityframework-core.html in TodoContext.cs

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
     #warning To protect potentially sensitive information in your connection string, 
     you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 
     for guidance on storing connection strings.
     
   optionsBuilder.UseMySQL("server=localhost;database=library;user=user;password=password");
}
=======

Now, using Code First approach, I need to create the table/entity in the database. So am using following code in Package Manager Console (Ref: https://learn.microsoft.com/en-us/ef/core/get-started/overview/first-app?tabs=visual-studio)

Install-Package Microsoft.EntityFrameworkCore.Tools
Add-Migration InitialCreate
Update-Database
---

Had to install Microsoft.EntityFrameworkCore as I got some error on Add-Migration. That error continued. It is related to dbContext. 

So am switching to EFCore tutorial style usage with UseMySQL as options:

builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));

The error continued ... Searching on the net did not give clear solutions. Version of packages mismatch was suggested as one reason!

Installed Microsoft.EntityFrameworkCore.Relational as it is listed as a dependency of MySql.EntityFrameworkCore 8.0.8.

Add-Migration InitialCreate gave the error again. This time I captured the error message:

Unable to create a 'DbContext' of type 'RuntimeType'. The exception 'Method 'get_LockReleaseBehavior' in type 'MySql.EntityFrameworkCore.Migrations.Internal.MySQLHistoryRepository' from assembly 'MySql.EntityFrameworkCore, Version=0.0.0.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d' does not have an implementation.' was thrown while attempting to create an instance. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
=================

The version numbers of the key packages installed seem to match.

=====================
System.TypeLoadException: Method 'Create' in type 'MySql.Data.EntityFrameworkCore.Query.Internal.MySQLSqlTranslatingExpressionVisitorFactory', https://stackoverflow.com/questions/64614651/system-typeloadexception-method-create-in-type-mysql-data-entityframeworkcor seems to have some related stuff. One recommendation is to use Pomelo.EntityFrameworkCore.MySql

Switched to Pomelo.EntityFrameworkCore.MySql - https://www.nuget.org/packages/Pomelo.EntityFrameworkCore.MySql/8.0.2 , https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql . It required uninstall of current version of Microsoft Entity Framework and install of 8.0.11 (< 8.0.999) version, also Tools of same version. Then I needed MySqlConnector to be installed.

Some code change was needed to provide MySQL server version number (and also delete MySql namespace references as I had uninstalled MySql packages). Then the 'Add-Migration InitialCreate' succeeded! I have not given the exact version number that my installation of MySQL uses but that will be a straightforward fix. Hmm. Very disappointing to see such difficulty in using MySQL with MySQL EF core packages, and seeming lack of easily searchable documentation/posts on the type of problems that I faced. I saw Pomelo reference in an above mentioned video but was hesitant to use that as I wanted to use official MySQL EF core package. Hmmm. Quite unsettling! But maybe there is an easy fix to the issue I faced with MySQL EF core package usage except that I could not figure it out.
------

builder.Services.AddDbContext<AppDbContext>(options => options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)));
----
Incorporated above server version code in my project.

Was able to do Update-Database also. As I had some earlier hardcoded server version migration as well as tables, I was able to drop the tables, delete the migration folder and recreate the migration and tables using:
Add-Migration InitialCreate
Update-Database
----

Hmm. Finally, I was able to fix this issue and get it into easy manageability zone. Have yet to test API with it. 
...
API worked as expected straight-away with data being accessed or updated in MySQL local database (which was started using xampp control panel).

Created public repo https://github.com/ravisiyer/DotNetTodoAPISQL and pushed code to it. The connection string is in the code with blank password but that's OK as my database is local and has only test data. Later, when needed, I will have a regular password and also, if I need this project code to run, modify the code to pick up connection string from some file that is not put in git and so uploaded to GitHub.
========================

======



Tutorial page: https://dotnet.microsoft.com/en-us/learn/aspnet/blazor-tutorial/intro (shows VSCode tutorial but video shows both VS2022 and VSCode tutorials (along with DotNet CLI or whatever that's called tutorial too).

In VS2022: New Project -> Blazor Web App ; Use Defaults and Create: BlazorApp1 project is created. Run without debug and the app. page shows up in browser! 
Notes from going through the project source code:
Bootstrap CSS library seems to be used. See wwwroot/bootstrap
BlazorApp1\Components\App.razor has:
    <link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
    <link rel="stylesheet" href="app.css" />
    <link rel="stylesheet" href="BlazorApp1.styles.css" />
--------

App.razor and Routes.razor in BlazorApp1\Components\ seem to the top-level pages which use MainLayout.razor and NavMenu.razor in BlazorApp1\Components\Layout\
Home.razor, Counter.razor, Weather.razor and Error.razor in BlazorApp1\Components\Pages\ seem to be the components that map to routes used in above pages/components.
Program.cs seems to be the main program which seems to invoke/use the App component.

Went through the code of above files. Had seen the videos related to this app which helped in me quickly getting a top-level idea of how the app works! I don't know the details but have got the general picture. That's quite a pleasant surprise. I must mention that exposure to Program.cs of .NET Core Web API programs allowed me to quickly get an overview idea of this app's Program.cs.

Making a trivial change to the app code and using Hot Reload worked straightaway with app page showing modified content. Hmm. I am impressed with the ease with which I could create this starter app, understand it at top-level and also make trivial changes to the app. 


Pt 9 video follow along needs VS2022 17.9 or later (around 0.30 in video). I have VS2022 17.11.5 installed as of 18 Nov. 2024. So I can follow along if I want to. As of now I am only seeing the video.

Finished Pt 9 video. [Excellent set of videos. Pace is quite fast at times but still manageable as topics are quite easy to understand at least roughly.]

Comments