Refit - метод FromForm/Multipart не работает с объектом запроса

У меня есть контроллер веб-API .NET 8 со следующим методом конечной точки:

[HttpPost()]
[Route("someRoute")]
[ProducesResponseType(typeof(SomeResponse), StatusCodes.Status200OK)]
public async Task<IActionResult> GetSomething([FromForm] SomeComplexRequest request, CancellationToken cancellationToken)
{
    //Map request to some MediatR command, send and get result

    return Ok(result.Value);
}

То, что он на самом деле делает внутри, не имеет отношения к моей проблеме. Эта конечная точка отлично работала до того, как я представил Refit в своем проекте (я использовал специальные реализации HttpClient).

Класс SomeComplexRequest выглядит следующим образом:

public sealed class SomeComplexRequest
{
    [Required]
    [FromForm(Name = "SomeID")]
    public Guid? SomeID { get; set; }

    [Required]
    [FromForm(Name = "Offset")]
    public int? Offset { get; set; }

    [Required]
    [FromForm(Name = "Length")]
    public int? Length { get; set; }

    public SomeComplexRequest(Guid? someID, int? offset, int? length)
    {
        SomeID = someID;
        Offset = offset;
        Length = length;
    }

    public SomeComplexRequest()
    {
    }
}

Моя проблема в том, что мой метод Refit работает ТОЛЬКО, если он написан так:

[Post("/api/SomeController/someRoute")]
[Multipart]
Task<ApiResponse<IEnumerable<SomeResponse>>> GetSomething(string someID, int offset, int length);

Насколько я понимаю, ситуация между SomeID Guid и строкой заключается в том, что Refit фактически не поддерживает Guid в качестве типа параметра. Это не идеально, но на самом деле это не такая уж большая проблема, поскольку контроллер в конечном итоге все равно понимает этот параметр независимо от того, отправлен ли он в виде Guid или строки. Что меня крайне раздражает, так это то, что метод Refit, похоже, требует перечисления всех отдельных параметров, составляющих мой запрос, вместо того, чтобы просто принимать экземпляр SomeComplexRequest независимо от того, является ли идентификатор Guid или строкой. Кажется, он не может разбить запрос на отдельные параметры. Эта подпись не работает:

[Post("/api/SomeController/someRoute")]
[Multipart]
Task<ApiResponse<IEnumerable<SomeResponse>>> GetSomething(SomeComplexRequest request);

У меня есть множество конечных точек, не являющихся Multipart (аннотированных FromBody в методе контроллера API), и они отлично работают с аналогичными сложными объектами запросов (в которых также есть Guids, заметьте). Это один из них :

[Post("/api/SomeOtherController")]
Task<ApiResponse<SomeOtherResponse>> AddSomeComplexThing(SomeEvenMoreComplexRequest);

Я не буду показывать этот запрос для краткости, но он имеет 8 параметров, включая строки, Guids и Enums. Этот метод имеет FromBody в параметре метода конечной точки, и он работает нормально.

Ожидается ли, что методы Multipart не поддерживают сложные объекты в качестве входных параметров, как это делает обычный метод с телом JSON?

Вы проверили документацию? У вас должна быть возможность опубликовать объект.

RobIII 29.04.2024 21:51

удаление [Multipart], возвращение моего сложного объекта в качестве параметра и аннотирование его с помощью [Body(BodySerializationMethod.UrlEncoded)], похоже, действительно помогает! Спасибо!

Martin 29.04.2024 22:03
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
121
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Моя проблема была частично связана с непониманием того, что такое многочастный запрос. Название вроде говорит само за себя, но это запрос, который состоит из нескольких запросов и обычно используется для загрузки файлов вместе с некоторыми метаданными.

Моя первая реализация конечной точки REST API FromForm должна была делать именно это, поэтому я ошибочно связал FromForm с Multipart, думая, что они должны идти вместе. Мой проблемный запрос здесь на самом деле представляет собой просто запрос с разбиением на страницы в форме, поэтому с самого начала в Multipart не было необходимости. Похоже, что именно аспект Multipart не позволяет использовать сложный объект в качестве параметра клиента. Как только я удалил его и указал [Body(BodySerializationMethod.UrlEncoded)] перед указанным объектом запроса, он начал работать.

Другие вопросы по теме

Как отфильтровать ключ из объекта второго уровня вложенного массива объектов
Преобразовать список массивов внутри объекта в элементы div, содержащие до четырех элементов в React
Конфигурация Sweetviz для принудительного анализа столбца типа объекта без преобразования
(объект JavaScript), если следующие значения больше первого значения на 1, добавьте значения в новый объект, если нет, игнорируйте значения
Есть ли способ создать класс без ограничения количества параметров универсального типа в С#?
Почему мой массив объектов не отображается должным образом из JavaScript в HTML?
Найдите объекты определенной длины внутри объекта
Как создать массив объектов в скрипте Google, используя object.map
Пытаюсь правильно расположить объекты в Маниме
Как строковые литералы хранятся в пуле строковых констант? Почему «Hello» + world не находится в пуле строковых констант?