.NET Core 2.2 Обязательные свойства, когда объект не является нулевым.Сложная вложенная модель - PullRequest
4 голосов
/ 11 апреля 2019

В .NET Core у меня есть модель, которая выглядит следующим образом.

public class Home
{
    [Required]
    public int Number {get;set;}
    public Address Address {get;set;} // This is not required
}
public class Address
{
   [Required]
   public string Street {get;set;}
   public IFormFile Picture {get;set;}

}

В методе контроллера, который выглядит следующим образом

[HttpPost]
public string AddHomes([FromForm]List<Home> homes) 
{
    if(!ModelState.IsValid)
    {
        return BadRequest();
    }
    // Do some saving
    return Ok();  
}

В запросе формы, который выглядит следующим образом

homes.Index: 0
homes[0].number: 1

В .NET Core2.2 первый дом в списке недействителен.Он работал в .NET Core 2.1

Я хочу, чтобы атрибут [Обязательный] проверялся только в том случае, если Адрес не null.Таким образом, дом может иметь либо адрес с улицей, либо вообще не иметь адреса.

Это достижимо в .NET Core 2.2?

Примечание. Обновлен пример для воспроизведения ошибки.Кажется, включение IFormFile заставляет класс адреса инициализироваться сам.

{
    "errors": {
        "homes[0].Address.Street": [
            "The Street field is required."
        ]
    },
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "80000009-0003-ff00-b63f-84710c7967bb"
}

Некоторое время назад я также открыл проблему для этого: https://github.com/aspnet/AspNetCore/issues/9321, если кто-то хочет продолжить.

1 Ответ

0 голосов
/ 11 апреля 2019

Требуемое поведение - это поведение для нулевых ссылочных свойств, и оно не изменилось в ASP.NET Core 2.2.Свойства указанного класса проверяются только в том случае, если сама ссылка не равна нулю.Если это не работает для вас, то единственный вывод состоит в том, что это ссылочное свойство имеет значение.Это может быть просто экземпляр по умолчанию (т. Е. new Foo()), при этом ни одно из под-свойств фактически не определено, но этого достаточно для запуска проверки.

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

public Bar Bar { get; set; } = new Bar();

Или

public Foo()
{
    Bar = new Bar();
}

Удалите это.

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

<input type="hidden" asp-for="Bar.Id" />

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

...