Как проверить, отправляет ли клиент пустой массив json с проверкой. NET Mvc? - PullRequest
0 голосов
/ 27 января 2020

У меня есть следующая модель представления:

public class EventViewModel
{
    [Required(ErrorMessage = "type can not be empty")]
    [JsonProperty("type")]
    [DisplayName("type")]
    public string Type { get; set; }

    [Required(ErrorMessage = "date can not be empty")]
    [JsonProperty("date")]
    [DisplayName("date")]
    public int Timestamp { get; set; }

    [JsonProperty("data")]
    public JObject Data { get; set; }
}

и следующее действие контроллера:

[Route("/api/v1.0/events")]
[HttpPost]
public async Task<IActionResult> Events([FromBody] List<EventViewModel> viewModel)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

Я ожидаю следующее JSON:

[
 {
  "type" : "open",
  "date" : 1567673607,
        "data" : {
             "message_id" : "lalalalala"
        }
 }
] 

Но что, если клиент отправит мне просто:

[]

пустой массив?

Я хотел бы показать сообщение проверки. Как я могу это сделать? Является ли это возможным?

Обновление

Возможно, объяснение проблемы не так понятно или я чего-то не понимаю. Я постараюсь это исправить.

Если у меня есть такие JSON:

{
 "items" :[
   {
    ...    
   }, 
   ...
   ]  
} 

Тогда все в порядке. Нет проблем. Я могу написать:

public class EventViewModelList
{
    [Required] 
    List<EventViewModel> EventViewModels {get; set;}
}

Но мой JSON это просто массив объектов. ТАК, я не могу.

И я могу сделать что-то вроде:

public async Task<IActionResult> Events([Required][FromBody] List<EventViewModel> viewModel)

Потому что это не работает. Поставить валидацию в контроллер? Нет ((Контроллер - это контроллер. Проверка - это проверка.

Я думаю, что мне нужен атрибут. Но атрибут уровня действия контроллера. Например:

 [Route("/api/v1.0/events")]
        [NotEmptyListOfViewModels]
        [HttpPost]
        public async Task<IActionResult> Events([FromBody] List<EventViewModel> viewModel)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

Я прав?

Ответы [ 2 ]

1 голос
/ 28 января 2020

Вы можете написать пользовательский механизм связывания, как показано ниже:

NotEmptyListOfViewModels

public class NotEmptyListOfViewModels:IModelBinder
{
    public async  Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
            throw new ArgumentNullException(nameof(bindingContext));

        //Get command model payload (JSON) from the body  
        String valueFromBody;
        using (var streamReader = new StreamReader(bindingContext.HttpContext.Request.Body))
        {
            valueFromBody =await streamReader.ReadToEndAsync();
        }
        var modelInstance = JsonConvert.DeserializeObject<List<EventViewModel>>(valueFromBody);

        if(modelInstance.Count==0)
        {
            bindingContext.ModelState.AddModelError("JsonData", "The json is null !");
        }

        bindingContext.Result = ModelBindingResult.Success(modelInstance);
    }
}

Действие события

[Route("/api/v1.0/events")]
[HttpPost]
public async Task<IActionResult> Events([ModelBinder(BinderType = typeof(NotEmptyListOfViewModels))]List<EventViewModel> viewModel)
{
     if (!ModelState.IsValid)
     {
        return BadRequest(ModelState);
     }

     return Ok();
}
0 голосов
/ 27 января 2020

Вы можете сделать следующее:

[Route("/api/v1.0/events")]
[HttpPost]
public async Task<IActionResult> Events([FromBody] List<EventViewModel> viewModel)
{
    if(viewModel == null || viewModel.Count == 0)
    {
       ModelState.AddModelError("","List can not be empty or null");
    }

    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    ..............
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...