Как десериализовать поле YAML как строку в YamlDotNet, если оно может быть скаляром или последовательностью?C#

Место общения программистов C#
Ответить
Anonymous
 Как десериализовать поле YAML как строку в YamlDotNet, если оно может быть скаляром или последовательностью?

Сообщение Anonymous »

Я работаю с данными YAML, хранящимися в базе данных PostgreSQL, и использую YamlDotNet для их десериализации в объект C#. Одно из полей, Cooking_instruction, может представлять собой либо одну строку, либо последовательность строк. Я хочу десериализовать это поле как одну строку в моем объекте C#, независимо от его формата в YAML.
Формат один:

Код: Выделить всё

name: Tomato Chutney Three Ways
description: Tomato Chutney in three ways: Spicy Tomato Garlic Chutney, Sweet Tomato Chutney, and Oil-Free No-Cook Tomato Chutney.
cooking_instruction: |
For the Spicy Garlic Tomato Chutney:
- Heat 2 tbsp of oil in a pan.
- Serve with idli, dosas, and parathas.

For the Sweet Tomato Chutney:
- Heat 2 tbsp of oil, add asafoetida, fennel seeds, nigella seeds, dried red chilies, tomatoes, and salt. Cook for 5-7 minutes.

For the Oil-Free & No-Cook Tomato Chutney:
- Soak dried red chillies in white vinegar for 30 minutes.
Формат второй:

Код: Выделить всё

name: Chicken Tikka Caesar Salad
description: Chicken Tikka Caesar Salad with romaine lettuce, bread croutons, and a flavorful dressing.
cooking_instruction:
- Take a bowl and combine hung curd, red chili powder, turmeric powder, coriander powder, garam masala, salt, ginger garlic paste, and chicken. Marinate for 15-20 minutes.
- Fry the marinated chicken in a grill pan with oil until crisp and golden brown.
Формат третий:

Код: Выделить всё

name: Crispy Pata Pork Recipe (Deep Fried Pork Hock)
description: An easy deep fried pork recipe from the Philippines that is sure to win hearts over. What other pork recipes do you want to see?
cooking_instruction: |
- Boil everything except for the hock and the baking soda.
- Bring the liquid to a simmer, add in the hock with the lid on.
А вот мой класс RecipeDto:

Код: Выделить всё

public class RecipeDto
{
public string Name { get; set; }
public string Description { get; set; }
public string CookingInstruction { get; set; }
}
Я хочу десериализовать поле Cooking_instruction как одну строку в объекте RecipeDto. Я попробовал следующий код десериализации:

Код: Выделить всё

var deserializer = new DeserializerBuilder()
.WithNamingConvention(UnderscoredNamingConvention.Instance)
.Build();

var recipeDto = deserializer.Deserialize(yamlData);
Однако я получаю сообщение об ошибке, когда Cooking_instruction представляет собой последовательность строк:

Код: Выделить всё

No node deserializer was able to deserialize the node into type System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
Как я могу справиться с этим сценарием и гарантировать, что Cooking_instruction десериализуется как одна строка, будь то простой скаляр или последовательность строк в YAML?
Правильно ли это обрабатывать десериализацию поля, которое может быть скаляром или последовательностью? Есть ли лучший подход или какие-либо улучшения этого решения?
Изменить:
На данный момент я могу решить с помощью этого кода большую часть формат:

Код: Выделить всё

public class StringOrArrayConverter : IYamlTypeConverter
{
public bool Accepts(Type type)
{
return type == typeof(string);
}

public object ReadYaml(IParser parser, Type type)
{
var result = string.Empty;

if (parser.TryConsume(out var scalar))
{
result = scalar.Value;
}
else if (parser.TryConsume(out _))
{
var lines = new List();
while (parser.Current is not SequenceEnd)
{
if (parser.TryConsume(out var line))
{
lines.Add(line.Value);
}
else
{
parser.MoveNext();
}
}
parser.MoveNext(); // Consume the SequenceEnd event
result = string.Join("\n", lines);
}
else
{
throw new InvalidOperationException("Unexpected YAML format");
}

return result;
}

public void WriteYaml(IEmitter emitter, object value, Type type)
{
var str = (string)value;
emitter.Emit(new Scalar(str));
}
}
Но я все еще борюсь с Format One

Подробнее здесь: https://stackoverflow.com/questions/786 ... -scalar-or
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»