I have an model with this structure:
public class MasterDTO
{
[Required(ErrorMessage = Constants.Message.DefaultTextFieldRequired)]
[MaxLength(250, ErrorMessage = Constants.Message.MaxLength)]
public string Comments { get; set; }
[Required(ErrorMessage = Constants.Message.DefaultTextFieldRequired)]
[AllowedExtensions(new[] { ".jpg", ".png", ".jpg", ".doc", ".docx", ".pdf" })]
public IFormFile File { get; set; }
public List<DetailDTO> Details { get; set; }
public MasterDTO()
{
this.Details = new List<DetailDTO>();
}
}
public class DetailDTO
{
public Int64 ElementId { get; set; }
public double LowerLimit { get; set; }
public double HigherLimit { get; set; }
[ValidValues(new[] {"A", "O", "R" })]
public string Status { get; set; }
[MaxLength(150, ErrorMessage = Constants.Message.MaxLength)]
public string UserAuthorization { get; set; }
public DateTime? AutorizationDate { get; set; }
}
In the controller:
public async Task<IActionResult> CreateProjectLimit([FromForm] MasterDto masterDto)
{
...
return Ok();
}
The html form is configured like multipart/form-data
I'm testing with swagger.
My problem is about Details property. I can get the comments and the file, but Details always is empty (empty, not null).
My approach is wrong about IFromFile? What's my mistake?
Thanks!
CodePudding user response:
Then custom model binder like below:
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;
}
}
Add the model binder to the model class:
public class MasterDTO
{
public string Comments { get; set; }
public IFormFile File { get; set; }
public List<DetailDTO> Details { get; set; }
public MasterDTO()
{
this.Details = new List<DetailDTO>();
}
}
[ModelBinder(BinderType = typeof(MetadataValueModelBinder))]
public class DetailDTO
{
public Int64 ElementId { get; set; }
public double LowerLimit { get; set; }
public double HigherLimit { get; set; }
public string Status { get; set; }
public string UserAuthorization { get; set; }
public DateTime? AutorizationDate { get; set; }
}

