JsonSubTypes
JsonSubTypes copied to clipboard
Inherited Class's DataAnnotations are used in ASP.NET
Is your feature request related to a problem? Please describe. When using ASP.NET for WebAPIs, DataAnnotations are used to automatically build BadRequest problem objects when Model Binding. However, models using JsonSubTypes do not enforce the DataAnnotations
Describe the solution you'd like I'd like DataAnnotations to be considered, and return BadRequest with a correct problem object when they are not met.
Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.
Additional context Microsoft Documentation on DataAnnotations in ASP.NET: https://docs.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-3.1
*** Source/destination types
public class AccountNewDto
{
[Required]
public string Name { get; set; }
[Required]
public string Product { get; set; }
public ExternalCashAccountType1Code CashAccountType { get; set; } = ExternalCashAccountType1Code.TRAN;
public AccountStatusEnum Status { get; set; } = AccountStatusEnum.enabled;
[Required]
public UsageEnum Usage { get; set; }
[Required]
public AmountInDto InitialBalance { get; set; }
[Required]
public string Msisdn { get; set; }
public AmountInDto AuthorizedLimit { get; set; }
}
[JsonConverter(typeof(JsonSubtypes), nameof(AmountInDto.Currency))]
[JsonSubTypes.JsonSubtypes.KnownSubType(typeof(GalacticCurrencyStandardInDto), CurrencyEnum.GSC)]
[JsonSubTypes.JsonSubtypes.KnownSubType(typeof(WizardingCurrencyInDto), CurrencyEnum.WC)]
public class AmountInDto
{
[Required]
public CurrencyEnum Currency { get; set; }
}
public class GalacticCurrencyStandardInDto : AmountInDto
{
[Required]
public long? Amount { get; set; }
}
public class WizardingCurrencyInDto : AmountInDto
{
[Required]
public long? Galleons { get; set; }
[Required]
public long? Sickles { get; set; }
[Required]
public long? Knuts { get; set; }
}
*** Source/destination JSON
{
"name": "Test Account",
"product": "Test Checking",
"cashAccountType": "TRAN",
"status": "enabled",
"usage": "PRIV",
"initialBalance": {
"amount": 5000,
"currency": "WC"
},
"msisdn": "555-555-5555"
}
This JSON should return:
{
"errors": {
"InitialBalance.Knuts": [
"The Knuts field is required."
],
"InitialBalance.Sickles": [
"The Sickles field is required."
],
"InitialBalance.Galleons": [
"The Galleons field is required."
]
},
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|73003b8f-4ac38906d681633e."
}
But instead it sets the properties to null
, despite the [Required]
annotation.
Does Newtonsoft.Json handle those ?
@PercyODI did you tried to use : https://www.newtonsoft.com/json/help/html/JsonPropertyRequired.htm ?
@manuc66 is skipping all the addnotations from DataAnnotations, I tried also Required, Range... and nothing is working.
I believe the problem is with asp.NET and not JsonSubTypes nor Newtonsoft.
See: https://github.com/dotnet/aspnetcore/issues/13829 (old) and https://github.com/dotnet/aspnetcore/issues/27882#issuecomment-785527786 (open)
I did a workaround where I specifically call TryValidateModel
on each object that is an abstract class:
foreach (var item in polymorphicList)
{
TryValidateModel(item);
}
if (!ModelState.IsValid)
{
return ValidationProblem(ModelState);
}
Thanks @bjarketrux . Your workaround helped me a lot!
Upd to
I believe the problem is with asp.NET and not JsonSubTypes nor Newtonsoft.
See: dotnet/aspnetcore#13829 (old) and dotnet/aspnetcore#27882 (comment) (open)
I did a workaround where I specifically call
TryValidateModel
on each object that is an abstract class:foreach (var item in polymorphicList) { TryValidateModel(item); } if (!ModelState.IsValid) { return ValidationProblem(ModelState); }
Also when TryValidateModel for nested types a call needs to be provided with a prefix.