Upgrading to .NET8 from desktop versions 4.8.X

Upgrade to Latest .NET


OVERALL
    Problems and differences encountered taking applications from .NET 4.8 desktop to .NET 8 .

SUGGESTION
   Rebuild the solution and project files from scratch with latest .NET 8.

PROBLEMS

APIs
   On later .NET APIs (post 4.8 desktop), you need to be extra carefully about how the inbound objects are declared.  So if integer in Postman, then must be integer in object.  In older .NET, they accept properties as strings.  
    Example - Say body in Postman is: 
       {
    "SettingData": 31000
}

   Pretend endpoint method is:
[HttpPut("cache/resettimer")] [Produces("application/json")] [ProducesResponseType(typeof(ResetCacheResponse), Status200OK)]
public async Task<HttpResponseMessage> MyMethod([FromBody] InputData input)

   Later .NET must be:
public class InputData { public int SettingData { get; set; }
}

Earlier .NET ok with:
public class InputData { public string SettingData { get; set; } }

Yaml
  1) Change from .NET 6.0 to .NET 8.0 
  2) Change runtime from win10-x64 to win-x64

Spatial Data

DbGeography & DbGeographyWellKnownValue were in desktop 4.8.1 but seem like they are not in the latest .NET 8.



DbGeography Class

  https://learn.microsoft.com/en-us/dotnet/api/system.data.spatial.dbgeography?view=netframework-4.8.1&viewFallbackFrom=net-8.0

DbGeographyWellKnownValue Class

  https://learn.microsoft.com/en-us/dotnet/api/system.data.spatial.dbgeographywellknownvalue?view=netframework-4.8.1



Example usage: 

    public DbGeography LatLong { get; set; } 

    public DbGeographyWellKnownValue MarketLatLong { get; set; }



I see Microsoft suggests: NetTopologySuite

  https://learn.microsoft.com/en-us/ef/core/modeling/spatial


Configuration
IConfiguration in Microsoft.Extensions.Configuration


[ExcludeFromCodeCoverage]
public static class ConfigExtensions
{

public static int GetInt(this IConfiguration config, string configValueName)
{
      try
      {
            return int.Parse(config.GetSection(configValueName).Value!);
      }
      catch
      {
            throw new Exception($"[E] The config value of {configValueName} is not an integer as expected.");
      }
}

/// <summary> WARNING - Do not use on Connection Strings, but rather use GetConnectionString() </summary>
public static string GetString(this IConfiguration config, string configValueName)
{
      return config.GetSection(configValueName).Value!;
}
}

Logging

Uses ILogger in Microsoft.Extensions.Logging


Global Using

   .NET 6 in Nov. 2021:  GlobalUsings.cs file in last project of the solution.

my usual contents are:

    global using Microsoft.Extensions.Configuration;

    global using Microsoft.Extensions.Logging;

    global using System.Diagnostics.CodeAnalysis;

contents for my model solutions are:

  using System.ComponentModel.DataAnnotations.Schema;

  using System.ComponentModel.DataAnnotations;


Http Client is left a shell of what it was:

1) HttpClient's loss of PostAsJsonAsync()

A: System.Net.Http.Json extension

2) The loss of IHttpClient is probably best handled by IHttpClientFactory introduced in .NET Core 2.1. See:  https://learn.microsoft.com/en-us/dotnet/core/extensions/httpclient-factory

a) So this is typically done in the API in the :  

public static IServiceCollection AddDependencies(this IServiceCollection services)  

services.AddHttpClient(); // Deal with HttpClient issue. Always prior to AddScoped below.

b) then in data access or other class, then private variable :

      private readonly HttpClient _httpClient;

c) in class, then in constructor parameters:

public CacheDataAccess(IConfiguration configHelper, IHttpClientFactory httpClientFactory, ILogger<CacheDataAccess> logger)

d) in class, then in constructor:

   _httpClient = httpClientFactory.CreateClient();


Could also be handled by custom wrapper or overloading the handler.  See:

https://swacblooms.com/mocking-the-httpclient-in-c/


DIFFERENCES

Both .NET 6 and 8

  Both require dealing with Nullables if coming from a 4.8 desktop



Contains() of Linq in .NET 8

  A breaking change in .NET 8:

Reference: https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/breaking-changes


 EF Core 7+ when connect to database

  Add TrustServerCertificate=True; to your connection strings to handle connecting to MS SQL Server from EF Core 7 or later.  

Reference: https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-7.0/breaking-changes?tabs=v7


AppSetting Changes in .NET 6

   The new .NET 6 way is appSettings.Json at top level and appSettings for each environ underneath such as appSettings.Development.json

   old 4.8 way: app.config 


New Solution/Project
I find I use these project templates the most and usually pin them:

Assembly Version, Copyright, etc.
   There is no longer an AssemblyInfo.cs that is included in the template, because all these values can be set inside the assembly's project file with its new properties in the PropertyGroup tag.











Comments

Popular posts from this blog

GHL Chat Bots for Webpage

GHL > Set website so shorter URL address