Подтвердить что ты не робот

Почему ModelState.IsValid не работает для моего метода ApiController, который имеет параметры с нулевым значением?

У меня есть метод ApiController, который принимает несколько параметров, например:

    // POST api/files
    public HttpResponseMessage UploadFile
    (
        FileDto fileDto,
        int? existingFileId,
        bool linkFromExistingFile,
        Guid? previousTrackingId
    )
    {
        if (!ModelState.IsValid)
            return Request.CreateResponse(HttpStatusCode.BadRequest);

        ...
    }

Когда я отправляю сообщение POST, я помещаю объект FileDto в тело запроса и другие параметры в строке запроса.

Я уже обнаружил, что я не могу просто опустить нулевые параметры - мне нужно поместить их в строку запроса с пустым значением. Таким образом, мой запрос выглядит так, когда я не хочу указывать значение для параметров с нулевым значением:

http://myserver/api/files?existingFileId=&linkFromExistingFile=true&previousTrackingId=

Это соответствует моему методу контроллера, и когда метод выполняется, нулевые параметры действительно null (как и следовало ожидать).

Однако вызов ModelState.IsValid возвращает false, и когда я просматриваю erorrs, он жалуется на оба параметра с нулевым значением. (Другие биты модели не имеют ошибок). Сообщение:

Требуется значение, но не указана в запросе.

Почему он думает, что требуется значение/нет? Разумеется, (a) значение не требуется для значения NULL, и (b) значение было (вроде) присутствующим - в нулевом виде пути?

4b9b3361

Ответ 1

В дополнение к первому ответу вы должны иметь возможность заставить свой рабочий код разрешить пропуски префикса на URL-адресе, если вы переместите все необязательные в конец объявления метода, и я всегда устанавливаю их в NULL для хорошей оценки

FileDto fileDto,
bool linkFromExistingFile,
Guid? previousTrackingId = null,
int? existingFileId = null

Но

Хорошая точка re: пустое значение URL с префиксом... это то же самое, что и NULL... Думая о строках, Is ?q= пустая строка или нуль

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

Так же:

public class ValuesController : ApiController
{
    // GET api/values
    public IEnumerable<string> Get(
        [FromUri(BinderType = typeof(TypeConverterModelBinder))] string q = null,
        [FromUri(BinderType = typeof(TypeConverterModelBinder))] int? value = null)
    {
        if (!ModelState.IsValid)
        {
            throw new HttpResponseException(HttpStatusCode.BadRequest);
        }

        return new string[] { value.HasValue ? value.Value.ToString() : "", q };
    }     
}

Ответ 2

Я решил это, переместив все параметры в один класс.

public class UploadFileModel {
   public FileDto FileDto { get; set; }
   public int? ExistingFileId { get; set; }
   public bool LinkFromExistingFile { get; set; }
   public Guid? PreviousTrackingId { get; set; }
}

public HttpResponseMessage UploadFile([FromUri]UploadFileModel model)
{
   // ...
}