使用 YamlDotNet 序列化动态模型时更改用于所有多行字符串的标量样式

Change the scalar style used for all multi-line strings when serialising a dynamic model using YamlDotNet

我正在使用以下代码片段将项目的动态模型序列化为字符串(最终导出到 YAML 文件)。

    dynamic exportModel = exportModelConvertor.ToDynamicModel(project);
    var serializerBuilder = new SerializerBuilder();
    var serializer = serializerBuilder.EmitDefaults().DisableAliases().Build();

    using (var sw = new StringWriter())
    {
        serializer.Serialize(sw, exportModel);
        string result = sw.ToString();
    }

任何多行字符串,例如:

propertyName = "One line of text
followed by another line
and another line"

以下列格式导出:

propertyName: >
  One line of text

  followed by another line

  and another line

注意额外的(不需要的)换行符。

根据这个YAML Multiline guide,这里使用的格式是折叠块标量样式。有没有办法使用 YamlDotNet 将所有多行字符串属性的此输出样式更改为文字块标量样式或其中一种流标量样式?

YamlDotNet documentation 展示了如何使用 WithAttributeOverride 将 ScalarStyle.DoubleQuoted 应用到特定的 属性,但这需要一个 class 名称并且要序列化的模型是动态的。这也需要列出每个 属性 来更改(其中有很多)。我想一次更改所有多行字符串属性的样式。

为了回答我自己的问题,我现在已经弄清楚如何通过派生 ChainedEventEmitter class 并覆盖 void Emit(ScalarEventInfo eventInfo, IEmitter emitter) 来做到这一点。请参阅下面的代码示例。

public class MultilineScalarFlowStyleEmitter : ChainedEventEmitter
{
    public MultilineScalarFlowStyleEmitter(IEventEmitter nextEmitter)
        : base(nextEmitter) { }

    public override void Emit(ScalarEventInfo eventInfo, IEmitter emitter)
    {

        if (typeof(string).IsAssignableFrom(eventInfo.Source.Type))
        {
            string value = eventInfo.Source.Value as string;
            if (!string.IsNullOrEmpty(value))
            {
                bool isMultiLine = value.IndexOfAny(new char[] { '\r', '\n', '\x85', '\x2028', '\x2029' }) >= 0;
                if (isMultiLine)
                    eventInfo = new ScalarEventInfo(eventInfo.Source)
                    {
                        Style = ScalarStyle.Literal
                    };
            }
        }

        nextEmitter.Emit(eventInfo, emitter);
    }
}