У меня есть требование, согласно которому у меня должно быть свойство, которое может связать его значение с помощью «debtAmount» или «Amount».
Я пытался получить аннотацию сверху, и она работает для долга, но значение не будет связываться с использованием «суммы».
Я хочу получить одну необязательную привязку для одного свойства (по сумме или по долгу).
Самый верхний ответ в этой теме не соответствует требованиям ремонтопригодности, поскольку в конечном итоге у него появятся дополнительные свойства, которые потребуют привязки нескольких имен. Поэтому я не хочу, чтобы на каждую общественную собственность добавлялась дополнительная частная собственность.
если вам нужно несколько свойств JSON во время десериализации, вы можете использовать JsonConverter
public class NewAccountRequestJsonConverter : JsonConverter<NewAccountRequest>
{
public override NewAccountRequest Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var newAccountRequest = new NewAccountRequest();
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
return newAccountRequest;
if (reader.TokenType == JsonTokenType.PropertyName)
{
string propertyName = reader.GetString();
if (propertyName == "amount" || propertyName == "debtAmount")
{
reader.Read();
newAccountRequest.Amount = reader.GetDecimal();
}
else
{
reader.Skip();
}
}
}
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, NewAccountRequest value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteNumber("amount", value.Amount);
writer.WriteEndObject();
}
}
Во время Deserialize
используйте это NewAccountRequestJsonConverter
как вариант
var options = new JsonSerializerOptions();
options.Converters.Add(new NewAccountRequestJsonConverter());
var result = JsonSerializer.Deserialize<NewAccountRequest>(jsonString, options);
это идеальное решение
Один из уже представленных подходов состоит в том, чтобы поместить некоторую логику сопоставления внутри JsonConverter (наследовать от него и переопределить некоторую логику).
Второй подход, как я вижу, может состоять в сопоставлении обоих полей с соответствующими полями Amount
и debtAmount
и иметь некоторый метод для получения этой информации на основе обоих свойств, что-то в этом роде:
public static class Extensions
{
public static decimal? GetAmount(this NewAccountRequest request) =>
request.Ammount ?? request.DebtAmount;
}
Вам нужно будет сделать поля сумм обнуляемыми, чтобы определить, когда они вообще не предоставляются. Или вы можете рассматривать значение по умолчанию 0
как «пустое значение», если 0 не будет допустимым числом.
я выберу первый подход, потому что со временем у этого класса появятся другие свойства.
@EdisonC на этот подход не повлияют новостные предложения, в конвертере вам необходимо добавить дополнительную логику для новостных реквизитов.
Это означает, что если есть 25 новых реквизитов, это значит, что будет еще 25, верно? Если да, то это будет проблемой в ремонтопригодности
@jason.kaisersmith, спасибо за уведомление. Я обновил вопрос