在 .NET中操作Yaml文件

作者:微信公众号:【架构师老卢】
4-27 18:21
20

概述:不幸的是,YAML 文件是当今所有开发人员日常生活的一部分;尽管它们非常容易出错,并且几乎不可能在没有 IDE 和架构信息的情况下进行编辑而不会经常遇到错误——向所有认为这是一个好主意的 CI 系统致以问候:事实并非如此——但我们必须接受我们必须处理它们的事实。在 .NET 中,YamlDotNet 库是处理 YAML 文件的常用选择。该库非常易于使用,并为大多数 YAML 文件提供了非常好的支持。处理 YAML 文件时,提供两种不同的选项:通过字典访问键值或反序列化为类。这两种方法都有其优点和缺点,但在大多数情况下,反序列化为类是更方便、更好的选择。YamlDotNet从 YAML 反序列化

不幸的是,YAML 文件是当今所有开发人员日常生活的一部分;尽管它们非常容易出错,并且几乎不可能在没有 IDE 和架构信息的情况下进行编辑而不会经常遇到错误——向所有认为这是一个好主意的 CI 系统致以问候:事实并非如此——但我们必须接受我们必须处理它们的事实。

在 .NET 中,YamlDotNet 库是处理 YAML 文件的常用选择。该库非常易于使用,并为大多数 YAML 文件提供了非常好的支持。

处理 YAML 文件时,提供两种不同的选项:通过字典访问键值或反序列化为类。这两种方法都有其优点和缺点,但在大多数情况下,反序列化为类是更方便、更好的选择。YamlDotNet

从 YAML 反序列化

对于类的反序列化,相应的类也是必需的;举个例子,我采用博客文章潜在标题的结构:

title: Handle Yaml Files with .NET  
description: This blog post shows a simple sample how to serialize and deserialize yaml files with .NET  
  
options:  
    isDraft: true  
    date: 2024-04-23T15:30:00Z  
author:  
    name: BEN ABT  
    twitter: https://twitter.com/Abt_Benjamin  
    linkedIn: https://www.linkedin.com/in/benjaminabt/  
    job:  
        company: Medialesson GmbH  
        description: Chief PullRequest Officer  
        website: https://media-lesson.com/

因此,类结构可以 1:1 实现:

public class BlogPost  
{  
    public string Title { get; set; } = null!;  
    public string Description { get; set; } = null!;  
    public Options Options { get; set; } = null!;  
    public Author Author { get; set; } = null!;  
    public string Content { get; set; } = null!;  
}  
public class Options  
{  
    public bool IsDraft { get; set; }  
    public DateTimeOffset Date { get; set; }  
}  
public class Author  
{  
    public string Name { get; set; } = null!;  
    public string Twitter { get; set; } = null!;  
    public string LinkedIn { get; set; } = null!;  
    public Job Job { get; set; } = null!;  
}  
public class Job  
{  
    public string Company { get; set; } = null!;  
    public string Description { get; set; } = null!;  
    public string Website { get; set; } = null!;  
}

截至目前,YamlDotNet 不支持任何记录;反序列化程序需要一个类,该类在属性中具有空构造函数和相应的 setter。

反序列化非常简单:

IDeserializer deserializer = new DeserializerBuilder()  
    .WithNamingConvention(CamelCaseNamingConvention.Instance)  
    .Build();  
  
// yamlBlogPost = string with yaml content  
BlogPost blogPost = deserializer.Deserialize<BlogPost>(yamlBlogPost);

然后,该对象将 YAML 文件中的相应值作为实例包含在内,可以照常访问。blogPost

序列化为 YAML

序列化也同样简单,只是相反:

ISerializer serializer = new SerializerBuilder()  
    .WithNamingConvention(CamelCaseNamingConvention.Instance)  
    .Build();  
  
string blogPostYaml = serializer.Serialize(blogPost);

完整示例

// --------------------------------------------------------------------
// This sample shows the handling of YAML files in .NET.
// The YamlDotNet library (https://github.com/aaubry/YamlDotNet) is used to serialize and deserialize YAML files.
// 2024-04-23 - https://schwabencode.com

// Runtime: .NET 8
// Sample Project: Console App
// Dependency: YamlDotNet

using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

// --------------------------------------------------------------------
// sample Yaml-File in style of a blog post header
string yamlBlogPost =
    """
    title: Handle Yaml Files with .NET
    description: This blog post shows a simple sample how to serialize and deserialize yaml files with .NET

    options:
        isDraft: true
        date: 2024-04-23T15:30:00Z
    author:
        name: BEN ABT
        twitter: https://twitter.com/Abt_Benjamin
        linkedIn: https://www.linkedin.com/in/benjaminabt/
        job:
            company: Medialesson GmbH
            description: Chief PullRequest Officer
            website: https://media-lesson.com/
    """;

// --------------------------------------------------------------------
// deserialize string as model
IDeserializer deserializer = new DeserializerBuilder()
    .WithNamingConvention(CamelCaseNamingConvention.Instance)
    .Build();

BlogPost blogPost = deserializer.Deserialize<BlogPost>(yamlBlogPost);

// Print blog post
Console.WriteLine(new string('-', 30));
Console.WriteLine($"## Print Blog Post Object");
Console.WriteLine($"Title: {blogPost.Title}");
Console.WriteLine($"\tDescription: {blogPost.Description}");
Console.WriteLine($"Options");
Console.WriteLine($"\tIs Draft: {blogPost.Options.IsDraft}");
Console.WriteLine($"\tDate: {blogPost.Options.Date:o}");
Console.WriteLine($"Author");
Console.WriteLine($"\tName: {blogPost.Author.Name}");
Console.WriteLine($"\tTwitter: {blogPost.Author.Twitter}");
Console.WriteLine($"\tLinkedIn: {blogPost.Author.LinkedIn}");
Console.WriteLine($"\tJob");
Console.WriteLine($"\t\tCompany: {blogPost.Author.Job.Company}");
Console.WriteLine($"\t\tDescription: {blogPost.Author.Job.Description}");
Console.WriteLine($"\t\tWebsite: {blogPost.Author.Job.Website}");

// --------------------------------------------------------------------
// create yaml serializer with options
ISerializer serializer = new SerializerBuilder()
    .WithNamingConvention(CamelCaseNamingConvention.Instance)
    .Build();

string blogPostYaml = serializer.Serialize(blogPost);

Console.WriteLine(new string('-', 30));
Console.WriteLine($"## Print Blog Post Text");
Console.WriteLine(blogPostYaml);

// --------------------------------------------------------------------
// sample models as classes, records are not supported today
public class BlogPost
{
    public string Title { get; set; } = null!;
    public string Description { get; set; } = null!;
    public Options Options { get; set; } = null!;
    public Author Author { get; set; } = null!;
    public string Content { get; set; } = null!;
}
public class Options
{
    public bool IsDraft { get; set; }
    public DateTimeOffset Date { get; set; }
}
public class Author
{
    public string Name { get; set; } = null!;
    public string Twitter { get; set; } = null!;
    public string LinkedIn { get; set; } = null!;
    public Job Job { get; set; } = null!;
}
public class Job
{
    public string Company { get; set; } = null!;
    public string Description { get; set; } = null!;
    public string Website { get; set; } = null!;
}

PS:请不要使用Yaml,如果你没有必要的话。每个人都讨厌yaml。

相关留言评论
昵称:
邮箱:
阅读排行