1

I'm using C#, YamlDotNet and following the example: How to deserialize YAML with YAMLDotNet?

But I'm getting the follow error:

Exception thrown: 'YamlDotNet.Core.YamlException' in YamlDotNet.dll
YamlDotNet.Core.YamlException: (Line: 1, Col: 1, Idx: 0) - (Line: 1, Col: 1, Idx: 0): Exception during deserialization ---> System.Runtime.Serialization.SerializationException: Property 'PlatForm' not found on type 'NAC21_Calculator.UserSoft'.
   at YamlDotNet.Serialization.TypeInspectors.TypeInspectorSkeleton.GetProperty(Type type, Object container, String name, Boolean ignoreUnmatched)
   at YamlDotNet.Serialization.NodeDeserializers.ObjectNodeDeserializer.YamlDotNet.Serialization.INodeDeserializer.Deserialize(IParser parser, Type expectedType, Func`3 nestedObjectDeserializer, Object& value)
   at YamlDotNet.Serialization.ValueDeserializers.NodeValueDeserializer.DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer)
   --- End of inner exception stack trace ---
   at YamlDotNet.Serialization.ValueDeserializers.NodeValueDeserializer.DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer)
   at YamlDotNet.Serialization.ValueDeserializers.AliasValueDeserializer.DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer)
   at YamlDotNet.Serialization.Deserializer.Deserialize(IParser parser, Type type)
   at YamlDotNet.Serialization.Deserializer.Deserialize[T](IParser parser)
   at YamlDotNet.Serialization.Deserializer.Deserialize[T](TextReader input)
   at NAC21_Calculator.YamlImporter.Deserialize(String yamlName) in D:\UserInput.cs:line 124
   at NAC21_Calculator.UserInput.GenerateBut_click(Object sender, EventArgs e) in D:\UserInput.cs:line 68
The program '[20556] NAC21_Calculator.exe' has exited with code 0 (0x0).

The yaml file content is:

PlatForm: windows
Version: 10
    # Software Info
SOFTWARE:
    Software-01:
        NAME    : MFS2020
        VERSION : 1.12.2015
        Customized  : true
    Software-02:
        NAME    : DCS
        VERSION : 6
        Customized  : false

The object definition:

public class UserSoft
    {
        public List<string> PlatForm { get; set; }
        public List<string> Version { get; set; }
        public List<software> SOFTWARE { get; set; }

        public class software
        {
            public string NAME { get; set; }
            public string VERSION { get; set; }
            public string Customized { get; set; }

        }
    }

And performing the deserialization whe pressing a button with:

private void GenerateBut_click(object sender, EventArgs e)
        {
           UserSoft obj = YamlImporter.Deserialize("file_template.yml");

           Console.WriteLine("Platform: {0}", obj.PlatForm);
           Console.WriteLine("Version: {0}", obj.Version);

           foreach (var soft in obj.SOFTWARE)
                  Console.WriteLine("Software: {0}", soft);

            }
            catch (Exception Ex)
            {
                Console.WriteLine(Ex.ToString());
            }
        }


 public class YamlImporter
    {
        public static UserSoft Deserialize(string yamlName)
        {
            StreamReader sr = new StreamReader(yamlName);
            string text = sr.ReadToEnd();
            var input = new StringReader(text);
            var deserializer = new DeserializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).Build();
            UserSoft deserializeObject = deserializer.Deserialize<UserSoft>(input); /* compile error */
            return deserializeObject;
        }
    }

I'm new in C# and this issue is the only that is really blocking me. Thanks in advance.

Mário Cera
  • 25
  • 1
  • 5
  • Just a drive-by comment: your `PlatForm` property is a `List`, but the value in the YAML file is a single string. Perhaps you should change the type to `string`? Admittedly I wouldn't expect that error message if that were the problem, but it's worth considering. – Jon Skeet Jan 23 '21 at 22:40
  • Thank you Jon. Good catch, but remains the same :( – Mário Cera Jan 25 '21 at 10:33

1 Answers1

2

There are a few problems here.

Firstly, your PlatForm and Version properties are of type List<string>, but the value is just a string.

Secondly, your SOFTWARE property doesn't represent a list, but a map - the strings "Software-01" and "Software-02" are effectively keys within a map.

Thirdly, you've explicitly stated that you want to deserialize with a camel-case naming convention, but your YAML doesn't actually use that convention.

Here's a minimal, complete example with those aspects corrected:

using System;
using System.Collections.Generic;
using System.IO;
using YamlDotNet.Serialization;

public class UserSoft
{
    public string PlatForm { get; set; }
    public string Version { get; set; }
    public Dictionary<string, software> SOFTWARE { get; set; }

    public class software
    {
        public string NAME { get; set; }
        public string VERSION { get; set; }
        public string Customized { get; set; }

    }
}

class Program
{
    static void Main(string[] args)
    {
        string text = File.ReadAllText("test.yaml");
        var deserializer = new DeserializerBuilder().Build();
        UserSoft deserialized = deserializer.Deserialize<UserSoft>(text);
        Console.WriteLine($"Platform: {deserialized.PlatForm}");
        Console.WriteLine($"Version: {deserialized.Version}");
        foreach (var pair in deserialized.SOFTWARE)
        {
            var value = pair.Value;
            Console.WriteLine($"{pair.Key}: Name={value.NAME}; Version={value.VERSION}; Customized={value.Customized}");
        }
    }
}

Output:

Platform: windows
Version: 10
Software-01: Name=MFS2020; Version=1.12.2015; Customized=true
Software-02: Name=DCS; Version=6; Customized=false

As an aside, I'd strongly recommend that you try to be consistent in your capitalization, and follow .NET naming conventions.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thank you Jon. You are the expert. You have been great by testing and correcting the big shit that I have made! I'm sorry but I'm really new to some details. I have to request you for more help. Probability is my environment, but var (key, value) is presenting error: Cannot infer the type of implicitly-typed deconstruction variable 'key' I'm trying to understand the error. Maybe you already know. – Mário Cera Jan 26 '21 at 11:23
  • Also deserialized have: Error CS1061 'KeyValuePair' does not contain a definition for 'Deconstruct' and no accessible extension method 'Deconstruct' accepting a first argument of type 'KeyValuePair' could be found (are you missing a using directive or an assembly reference?) – Mário Cera Jan 26 '21 at 11:26
  • @MárioCera: I suspect that's just a matter of me using a more modern version of the framework than you. I've edited the sample to avoid needing deconstruction. – Jon Skeet Jan 26 '21 at 11:45
  • That's it. Thank you very much. – Mário Cera Jan 26 '21 at 15:41