Home > Enterprise >  ASP.NET Web API [FromForm] custom binding for list of objects property does not work from Postman, b
ASP.NET Web API [FromForm] custom binding for list of objects property does not work from Postman, b

Time:01-04

I have a controller method to accept multipart/form-data request with primitive types, File and List of objects. I saw that I need custom model binder when I have complex data type using FromForm and I made one, but the problem is that binding works from Swagger, but not from Postman.

Here is my controller method first:

 public async Task<IActionResult> Post([FromForm] AddRequest addRequest)
 {
    var result = await _service.AddAsync(addRequest);
    if (result.Success)
     {
        return Ok(result);
     }
    return BadRequest();
 }

My request looks like this:

 public class AddRequest
 {
   public string? Name { get; set; }
   public string? Description { get; set;}
   public IFormFile? File { get; set; }
   public IEnumerable<LocaleViewModel>? Locales { get; set; }
 }

And here is my viewmodel:

[ModelBinder(BinderType = typeof(MetadataValueModelBinder))]
public class LocaleViewModel
{
   public long Id { get; set; }
   public string Code { get; set; }
 }

And finally model binder:

 public class MetadataValueModelBinder : IModelBinder
 {
      public Task BindModelAsync(ModelBindingContext bindingContext)
      {
        if (bindingContext == null)
            throw new ArgumentNullException(nameof(bindingContext));
            var values = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

            if (values.Length == 0)
                return Task.CompletedTask;
            var options = new JsonSerializerOptions() { PropertyNameCaseInsensitive = true };

            var deserialized = JsonSerializer.Deserialize(values.FirstValue, bindingContext.ModelType, options);

            bindingContext.Result = ModelBindingResult.Success(deserialized);
            return Task.CompletedTask;
        }
 }

So, when I fire request from Swagger, binding is done correctly and model name is Locales, but when I do it from Postman or my SPA, binding is not working and model name is Locales[0]. Am I missing something in my model binder or I'm doing everything completely wrong?

I was trying to understand how ValueProvider.GetValue works but with no success.

CodePudding user response:

How do you pass parameters in postman? Please try like this:

enter image description here

enter image description here

Second exeution: enter image description here

Test Result: enter image description here

  • Related