.Net 8 migration guide

Main changes

The MVC layer of the applications has been converted to AspNet Core. This impacts all aspects of that project including the controllers, view models, models, authentication, routing, initialization, serialization and many other aspects of the application.

Main architecture differences in the AspNet Core server:

  • The MVC layer has been completely split into the Razor version which will continue to be compiled in .Net Framework 4.8, and the API version which will be compiled to DotNet 8.0 (Core). Only generating VueJs will make use of this new MVC layer and will be the focus of development going forward.
  • Generating to MVC (Razor) will use the old layer and is now marked for deprecation, supporting only bug fixes.
  • Core now opens the way for lightweight and flexible deployment strategies:
    • Better Azure cloud support
    • Linux support
    • Containerized (Docker) support Third-party dependency impacts: Reporting services have severe limitations and no longer support report viewer in Core
  • Crystal Reports is no longer supported in Core
  • Document conversion based on NetOffice will require an additional external service deployment.
  • PDF creation based on iTextSharp has been downgraded to the last open-source version recompiled to Core. It may have severe limitations depending on the use case.

Main coding differences in the AspNet Core server:

  • Requests must explicitly state where the parameter is going to be parsed from with FromBody, FromQuery and similar attributes.
  • The body of a request must be read by a single parameter in its entirety
  • ViewModels and Models that inherit from their respective Base classes now require the UserContext in the constructor
  • An empty constructor is supplied for Deserialization purposes only, after it some code must ensure an Init(userContext) call is made before any other method or property of that instance is called.
  • Post-deserialization initializations can be made in ActionFilters, but avoid making new code depending on that.
  • In AspNet Core no classes are accessible statically. Everything must be an instance, usually obtained through dependency injection or by plain old parameter passing. HttpContext, Session, and many others are not available globally anymore.
  • Authentication state changes should be handled by HttpContext.SignInAsync() and HttpContext.SignOutAsync()
  • All ActionResult methods inheriting from ControllerBase now require Authentication by default. This is the inverse of the current MVC implementation. Instead, mark explicitly the methods you need to allow public access with AllowAnonymous.
  • Never call or store things in session directly, always go through a UserContext method and abstract away the implementation.
  • Avoid using Clone() on the Navigation, in VueJs each request gets its own deserialized instance of Navigation. Instead, you can mark the current controller with IsStateReadonly = true so that any temporary changes to the Navigation are not reflected on the client side.
  • Serialization is now implemented with System.Text.Json instead of Newtonsoft.Json. This impacts all class attributes and serialization converters. Avoid relying upon attributes when possible so data transfer classes can be reusable between MvcRazor and MvcApi.

Development environment

For full development support, only Visual Studio 2022 17.8.3and above is supported. You will also need to installDotNet 8 SDKandPNPM`.

The VueJs frontend and MVC controllers are now two separate projects. During development, you should start them both independently.

Visual Studio provides a startup configuration to ease this task.

  • Go to "Project > Configure Startup Projects ..."
  • Select the option "Multiple startup projects"
  • Set the action of "GenioMvc" to "Start"
  • Set the action of "ClientApp" to "Start"

When you press F5 (debug) both processes should be launched and the debugger should allow you to put breakpoints in the code.

The VueJs client has a small retry mechanism in case the server side is not responding. If it takes too long to startup you might need to refresh the browser manually.

Take into consideration that in development both processes are running in different TCP ports. Vite will proxy all API requests to the port where the Core process is running. This setup enables hot reloading for both client and server-side code edits, speeding up code development.

In production, the entire site will run from a single port.

Manual code guide

  • Remove references to:
    • [HttpParamAction]
    • [AuthorizeForUsers]
    • JsonRequestBehavior.AllowGet
    • JsonRequestBehavior.DenyGet
  • Public methods that need to bypass authentication must be explicitly marked with [AllowAnonymous]
  • Instead of return new JsonResult() use return Json(data)
  • Replace usages of the global UserContext.Current with the local m_userContext
  • Contructor calls will require the value for UserContext for all classes inheriting from:
    • ViewModelBase
    • ModelBase
    • GridTableList
  • Various static methods also require an additional UserContext value to be passed by the parameter:
    • Find
    • All
    • Where
  • Manual controllers that declare the header of the web method must now receive a single object marker with [FromBody] attribute

Old

[AuthorizeForUsers]
public ActionResult MyMethod(string id, string name, DateTime date) { }

New

public class MyMethodRequest
{
    public string id {get;set;}
    public string name {get;set;}
    public DateTime date {get;set;}
}
public ActionResult MyMethod([FromBody] MyMethodRequest request) { }
  • ClientApp has changed the directory, so if you have any copy files associated with your project you will need to move them from <output>/GenioMVC/ClientApp to the new directory in <output>/ClientApp.
  • If you need to share code between the old MVC code and the Core version you can use manual code with the tag MVCAPI for the Core version and keep the MVC tagged code. Take into consideration that old MVC code will be increasingly deprecated so plan your migration accordingly.

Deployment requirements

Asp Net Core applications can run directly from the command line, however this is not advised since it will lack any kind of recovery mechanism. In a Windows-based deployment, it is still best to deploy the application under IIS.

For an IIS deployment, the AspNet Core application should be published with the properties:

  • Configuration: Release
  • Target Framework: net8.0
  • Deployment Mode: Framework-dependent
  • Target runtime: Portable

You should be able to target win-x64 but it should be equivalent to Portable when running the publish operation in a Windows computer.

Due to the large reusability of the base framework, we do not advise at this point to publish in self-contained mode. Instead, install the .Net framework 8.0 runtime in the production system.

You will need to install the .NET Core Hosting Bundle of the correct .Net 8.0 version, on the production machine.

When configuring the application pool, set the .Net Clr Version to No Managed Code, and Managed pipeline mode to Integrated.

Create a separate application pool for each AspNet Core application. Asp.Net core does not support multiple applications hosted in the same application pool.

Security in Core is significantly more strict, only Https deployments are supported. Authentication and other security features might simply refuse connections otherwise. If you are behind a reverse proxy, disabling https in the Core app might be necessary. To do so modify the appsettings.json file to the appropriate value of https_redirect:

  • none - to disable https redirection of unsecured http requests
  • redirect - (default) for AspnetCore to reply with a 307 redirect code to http request
  • hsts - for strict enforcement of https (this is an experimental setting)

If your https port is not the default or if you have multiple port bindings then you might need to set that port with the property https_port.

Note that AspNet Core does not natively use web.config, it uses appsettings.json. Some configurations have been routed to web.config for retro-compatibility, but not all will be observed by the application. The configuration sections recognized are:

  • Machine key
  • Log4net
  • Session cookie name and timeout
  • Authentication cookie name

All other configurations are only read by IIS or simply ignored.