суббота, 18 января 2025 г.

Ошибка "no matching manifest for windows/amd64 10.0.17763 in the manifest list entries"

Вот такая любопытная ошибка у меня возникла на изменении базового образа для моего Docker контейнера при переходе с NET Core 7.0 на NET Core 8.0: 
no matching manifest for windows/amd64 10.0.17763 in the manifest list entries

В моих образах нужна компиляция проекта, использовался образ "mcr.microsoft.com/dotnet/sdk:7.0" и он отлично работал для Windows: 
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS builder

Это multi-arch образ и можно использовать одно и то же имя сразу для образов Linux и Wndows: docker сам выберет подходящий вариант под текущие настройки.

Такую же multi-arch конфигурацию я ожидал от образа "mcr.microsoft.com/dotnet/sdk:8.0", который выложен на docker hub: https://hub.docker.com/r/microsoft/dotnet-sdk 

И это обещает дока: "mcr.microsoft.com/dotnet/sdk:8.0 - .NET 8, with SDKs included, on Linux and Windows (multi-arch)" на странице https://learn.microsoft.com/en-us/dotnet/architecture/microservices/net-core-net-framework-containers/official-net-docker-images?source=docs 

Однако, при запуске я получил ошибку "no matching manifest for windows/amd64 10.0.17763 in the manifest list entries". По описаниям эта ошибка часто возникает при использовании Linux образа когда Docker работает в режиме Windows.

Видимо образ "mcr.microsoft.com/dotnet/sdk:8.0" перестал быть multi-arch.

В исходниках этого образа на github есть отдельные описания для каждой OS (скорее всего это означает и отдельные имена): https://github.com/dotnet/dotnet-docker/tree/main/src/sdk/8.0

А в примерах использования этого контейнера на github (https://github.com/dotnet/dotnet-docker/blob/main/samples/build-in-sdk-container.md) в разделе "Windows using Windows containers" явно указывается специальный тег для windows: "docker run --rm -v ${pwd}:c:\app -w c:\app mcr.microsoft.com/dotnet/sdk:9.0-nanoserver-ltsc2022 ..."

Т.е. мне тоже нужно указать конкретный тег базового образа:
FROM mcr.microsoft.com/dotnet/sdk:8.0-nanoserver-ltsc2022 AS builder

С этим вариантом базового образа мои задачи в docker контейнерах снова заработали

пятница, 10 января 2025 г.

FromQueryAttribute: неявное преобразование или неявные грабли?

В NetCore можно сделать контроллер и объявить в нем метод:

[ApiController]
public class PersonsController : ControllerBase {
 public EditModelApiDTO GetEditObjectModel(FromQuery(Name = PersonIdName)] int targetObjectId) { ...

Метод декларирует параметр с именем PersonIdName и в url нужно добавить для него значение: 
http://localhost:5555/api/Persons/GetEditObjectModel?PersonId=1

Дополнительно к такому варианту можно сделать вызов без явной передачи значения для этого параметра:
http://localhost:5555/api/Persons/GetEditObjectModel
В этом раскладе значением для аргумента targetObjectId будет '0': в url параметр с нужным именем не найден, значением считается 'null', оно неявно преобразуется в '0' и затем передается как значение для аргумента targetObjectId.

Так получилось, что в моем тестовом окружении '0' был именно тем значением, которое нужно было передать в запросе и приложение работало верно (т.е. "все работает", хотя клиентский код не передавал значение для PersonId).

При переходе на новое окружение мой код перестал работать правильно и появилась ошибка "данные не найдены": в новом окружении вообще не было данных для ключевого значения '0'. В этом смысле мне немного повезло и я сразу увидел хоть какое-то сообщение об ошибке: если бы были данные для ключевого значения '0', то мой код их бы и обработал без всяких сообщений и я бы наверняка не заметил неверную работу приложения, ведь по контексту вызова нужна обработка данных по другому ключевому значению.

Что бы сразу получать ошибку в этом раскладе мне нужно было добавить атрибут System.ComponentModel.DataAnnotations.RequiredAttribute:
public EditModelApiDTO GetEditObjectModel([Required, FromQuery(Name = PersonIdName)] int targetObjectId) { ...

В тексте новой ошибки есть указание на имя required параметра: "errors":{"personId":["The targetObjectId field is required."]}}