Несколько дней назад я начал работать над развертыванием своего старого веб-приложения (acapedia) на онлайн-сервере.
Поскольку серверная часть приложения была в .NET, мне нужно было найти сервер, поддерживающий развертывание .NET.

Как только я нашел подходящего хостинг-провайдера, следующая проблема, с которой я столкнулся, заключалась в том, что мое приложение было написано на .NET 2.1, но оно не поддерживалось хостинг-провайдером, так как уже некоторое время назад достигло EOL.

Короче говоря; Мне пришлось перейти с .NET 2.1 на последнюю версию .NET.

В этой статье представлено краткое руководство о том, как это сделать, с какими проблемами вы можете столкнуться и как их решить.

Выбор правильной версии

Существует 2 типа релизов для .NET, а именно:

  • Долгосрочная поддержка (LTS)
    Выпуски LTS поддерживаются в течение трех лет после первоначального выпуска.
  • Standard Term Support (STS)
    Выпуски STS поддерживаются в течение шести месяцев после последующего выпуска STS или LTS. Релизы выходят каждые 12 месяцев, поэтому период поддержки STS составляет 18 месяцев.

Если у вас нет особых потребностей, почти всегда лучше перейти на последнюю версию LTS, поскольку она предоставляет вам версию, поддерживаемую Microsoft, почти на 3 года, а не на 18 месяцев.

В то время, когда я обновлялся, последней версией LTS была .NET 6, и именно на нее я решил перейти.
Наряду с тем, что это была последняя версия LTS, у нее было еще несколько преимуществ, таких как:

Установка .NET 6

Чтобы узнать все версии .NET SDK, установленные на вашем компьютере, просто выполните следующую команду:

dotnet --list-sdks

Если вы не видите .NET 6 в списке результатов приведенной выше команды, вот ссылка, по которой вы можете напрямую загрузить установщик. Или вы можете использовать Visual Studio или предпочтительную IDE, чтобы загрузить и установить его.

Изменение целевых рамок всех проектов

Первое, что вы должны изменить, — это целевую структуру всех ваших .NET-проектов.

Для этого перейдите в файл .csproj каждого из ваших проектов и измените свойство TargetFramework на .net6.0.

<TargetFramework>net6.0</TargetFramework>

Пакеты обновлений

Если вы используете Visual Studio, щелкните правой кнопкой мыши решение и выберите Manage nuget packages.

При обновлении следует помнить одну вещь: вы должны проверить Dependencies часть пакета и убедиться, что SDK, упомянутый там, эквивалентен версии SDK, до которого вы обновляетесь.
В нашем случае это должно быть .net6.0.

В то время, когда я обновлялся, было несколько пакетов, предназначенных для .net7.0 (Стандартная поддержка), так как это было последним на тот момент, но когда я обновлялся до .net6.0 (Долгосрочная поддержка), я выбрал версии пакетов, совместимые с .net6.0.

Критические изменения Entity Framework

1. Нет больше Newtonsoft.Json

Начиная с .NET 3.0, Microsoft отказалась от Newtonsoft.Json в пользу собственного System.Text.Json.
У каждого есть свои плюсы и минусы, вы можете узнать больше об этом в следующем:
Newtonsoft.Json vs System .Текст.Json

Так что теперь, если вы все еще хотите использовать Newtonsoft.Json вместо System.Text.Json от Microsoft, вам нужно немного настроить Startup.cs.
Если вы используете MVC, который я использовал для своего приложения, это так же просто, как:

services.AddMvc().AddNewtonsoftJson();

2. Builder.UseMySql(string) больше не существует

Метод расширения UseMysql(string) на DbContextOptionsBuilder теперь требует второго параметра, указывающего версию сервера. Простое исправление для повторной компиляции — автоматическое определение версии. например

builder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString));

3. Отсутствует Relational() в IMutableProperty

Relational() отсутствует в IMutableProperty. Вместо этого вы можете заменить это вызовом SetColumnType(string).

4. CorsAuthorizationFilterFactory отсутствует

Мы можем просто удалить фильтр MVC.

5. Изменения политики CORS

Политика CORS теперь более строгая. Использование CorsPolicyBuilder с очень открытой политикой, разрешающей как заголовок, так и учетные данные, приводит к исключению, похожему на:

Application startup exception: System.InvalidOperationException: The CORS protocol does not allow specifying a wildcard (any) origin and credentials at the same time. Configure the CORS policy by listing individual origins if credentials needs to be supported.

Это можно легко решить, удалив либо вызов AllowCredentials, либо вызов AllowAnyOrigin, в зависимости от ваших обстоятельств. например

var corsBuilder = new CorsPolicyBuilder();
corsBuilder.AllowAnyHeader();
corsBuilder.AllowAnyMethod();
corsBuilder.AllowAnyOrigin();
// corsBuilder.AllowCredentials();

6. IHostingEnvironment устарел

Замените на IWebHostEnvironment.

7. Изменения MVC

Вы можете заменить AddMvc() на AddControllers(), если у вас есть проект API. Чуть подробнее разница обсуждается здесь.

Вы также можете заменить строку app.UseMvc() на:

app.UseRouting();
app.UseEndpoints(options =>
{
    options.MapControllers();
});

Это в основном из соображений производительности и совместимости с новыми образцами кода и практиками. UseRouting() должно стоять перед UseEndpoints(), чтобы избежать исключения при запуске.

8. Удалите ссылки на Microsoft.AspNetCore.App.

Microsoft.NET.Sdk.DefaultItems.Shared.targets(111, 5): [NETSDK1080] A PackageReference to Microsoft.AspNetCore.App is not necessary when targeting .NET Core 3.0 or higher. If Microsoft.NET.Sdk.Web is used, the shared framework will be referenced automatically. Otherwise, the PackageReference should be replaced with a FrameworkReference.

Найдите все существующие ссылки на Microsoft.AspNetCore.App и удалите их, так как теперь они избыточны.

9. Привязка модели

Числа больше нельзя неявно десериализовать как строки. например учитывая следующую модель данных:

public class AddressModel
{
    [StringLength(4)]
    public string postCode { get; set; } = "";
}

и следующую полезную нагрузку:

{ "postCode":2145 }

Это приводит к следующему ответу 400:

{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"00-9d782bbecbc2107262258e79a7df080e-8d29b1c98b0ea23e-00","errors":{"$.address.postCode":["The JSON value could not be converted to System.String. Path: $.address.postCode | LineNumber: 0 | BytePositionInLine: 151."]}}

Это похоже на побочный эффект замены .NET Core 3 Newtonsoft.Json на System.Text.Json в качестве сериализатора JSON по умолчанию. Установка Microsoft.AspNetCore.Mvc.NewtonsoftJson и добавление AddNewtonsoftJson() к существующей строке AddControllers() в Startup.cs, по-видимому, решает эту проблему. Если вы использовали .NET Core 2.1, то в любом случае Newtonsoft.Json был сериализатором JSON по умолчанию, поэтому может иметь смысл сохранить это в любом случае, просто чтобы предотвратить появление небольших проблем, подобных этой.

Мне помогла эта статья на codeproject, когда я обновлял свой проект. Моя текущая статья также берет фрагменты из нее, здесь и там, а связанная статья немного более обширна. Я только что рассмотрел части, которые представляли для меня большую ценность, если вы ищете больше, чем то, что охватывает эта статья, или если ваш проект немного более обширен, статья может оказаться полезной и для вас.

Если вы обнаружите, что я упустил что-то важное, или если вы также недавно обновили свой проект, упомяните свое понимание ниже в комментариях, я также буду рад включить это в статью.

Удачного кодирования!