使用 yamldotnet 反序列化 yaml 时出错
Error deserializing yaml with yamldotnet
我正在玩一些 yaml 和 YamlDotNet
但是我在反序列化一些看起来很容易的问题。
这是我的 yaml 文件:
---
# Folders to secure (with recursive content)
folders2Secure:
- .git
- .vs
folders2Delete:
- packages
- obj
- bin
- TestResults
- node_modules
...
相关 C# 对象:
public class FolderPreferences
{
public List<string> Folders2Secure { get; set; }
public List<string> Folders2Delete { get; set; }
}
使用此代码反序列化:
public class ConfigurationReader
{
public FolderPreferences Read(string configurationFile)
{
var input = new StringReader(configurationFile);
var deserializerBuilder = new DeserializerBuilder().WithNamingConvention(new CamelCaseNamingConvention());
var deserializer = deserializerBuilder.Build();
var result = deserializer.Deserialize<FolderPreferences>(input);
return result;
}
}
我有这个 error/stack 比赛:
YamlDotNet.Core.YamlException was unhandled
HResult=-2146233088
Message=(Line: 1, Col: 1, Idx: 0) - (Line: 1, Col: 19, Idx: 18): Exception during deserialization
Source=YamlDotNet
StackTrace:
at YamlDotNet.Serialization.ValueDeserializers.NodeValueDeserializer.DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer) in C:\projects\yamldotnet\YamlDotNet\Serialization\ValueDeserializers\NodeValueDeserializer.cs:line 75
at YamlDotNet.Serialization.ValueDeserializers.AliasValueDeserializer.DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer) in C:\projects\yamldotnet\YamlDotNet\Serialization\ValueDeserializers\AliasValueDeserializer.cs:line 134
at YamlDotNet.Serialization.Deserializer.Deserialize(IParser parser, Type type) in C:\projects\yamldotnet\YamlDotNet\Serialization\Deserializer.cs:line 315
at YamlDotNet.Serialization.Deserializer.Deserialize[T](TextReader input) in C:\projects\yamldotnet\YamlDotNet\Serialization\Deserializer.cs:line 257
at Ebys.CleanFolders.Library.ConfigurationReader.Read[T](String configurationFile) in E:\WorkingGit\bitbucket\CleanFolders\Ebys.CleanFolders.Library\ConfigurationReader.cs:line 21
at Ebys.CleanFolders.ConsoleUi.Program.Main(String[] args) in E:\WorkingGit\bitbucket\CleanFolders\Ebys.CleanFolders\Program.cs:line 27
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
HResult=-2147467262
Message=Invalid cast from 'System.String' to 'Ebys.CleanFolders.Library.FolderPreferences'.
Source=mscorlib
StackTrace:
at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)
at System.String.System.IConvertible.ToType(Type type, IFormatProvider provider)
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at YamlDotNet.Serialization.Utilities.TypeConverter.ChangeType(Object value, Type destinationType, CultureInfo culture) in C:\projects\yamldotnet\YamlDotNet\Serialization\Utilities\TypeConverter.cs:line 128
at YamlDotNet.Serialization.NodeDeserializers.ScalarNodeDeserializer.YamlDotNet.Serialization.INodeDeserializer.Deserialize(IParser parser, Type expectedType, Func`3 nestedObjectDeserializer, Object& value) in C:\projects\yamldotnet\YamlDotNet\Serialization\NodeDeserializers\ScalarNodeDeserializer.cs:line 96
at YamlDotNet.Serialization.ValueDeserializers.NodeValueDeserializer.DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer) in C:\projects\yamldotnet\YamlDotNet\Serialization\ValueDeserializers\NodeValueDeserializer.cs:line 60
InnerException:
知道我做错了什么吗?
已编辑
GVim 中 Hexa 视图中的文件。
我猜你的文件开头有额外的内容,这些内容被解释为包含单个字符串的初始文档,因此是异常。检查以下 fiddle,它使用您的代码并按预期工作:
https://dotnetfiddle.net/tilGHT
然后与这个比较,在文档开始之前添加了额外的文本:
https://dotnetfiddle.net/d72Jut
您可以尝试删除开头的 ---
,因为无论如何它都是可选的。
问题是您正在创建 StringReader
,它是针对您指定的字符串的 reader,而不是针对文件的 reader。您需要使用 File.OpenText
或类似的 API 从文件中读取:
public FolderPreferences Read(string configurationFile)
{
using (var input = File.OpenText(configurationFile))
{
var deserializerBuilder = new DeserializerBuilder().WithNamingConvention(new CamelCaseNamingConvention());
var deserializer = deserializerBuilder.Build();
var result = deserializer.Deserialize<FolderPreferences>(input);
return result;
}
}
我正在玩一些 yaml 和 YamlDotNet
但是我在反序列化一些看起来很容易的问题。
这是我的 yaml 文件:
---
# Folders to secure (with recursive content)
folders2Secure:
- .git
- .vs
folders2Delete:
- packages
- obj
- bin
- TestResults
- node_modules
...
相关 C# 对象:
public class FolderPreferences
{
public List<string> Folders2Secure { get; set; }
public List<string> Folders2Delete { get; set; }
}
使用此代码反序列化:
public class ConfigurationReader
{
public FolderPreferences Read(string configurationFile)
{
var input = new StringReader(configurationFile);
var deserializerBuilder = new DeserializerBuilder().WithNamingConvention(new CamelCaseNamingConvention());
var deserializer = deserializerBuilder.Build();
var result = deserializer.Deserialize<FolderPreferences>(input);
return result;
}
}
我有这个 error/stack 比赛:
YamlDotNet.Core.YamlException was unhandled
HResult=-2146233088
Message=(Line: 1, Col: 1, Idx: 0) - (Line: 1, Col: 19, Idx: 18): Exception during deserialization
Source=YamlDotNet
StackTrace:
at YamlDotNet.Serialization.ValueDeserializers.NodeValueDeserializer.DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer) in C:\projects\yamldotnet\YamlDotNet\Serialization\ValueDeserializers\NodeValueDeserializer.cs:line 75
at YamlDotNet.Serialization.ValueDeserializers.AliasValueDeserializer.DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer) in C:\projects\yamldotnet\YamlDotNet\Serialization\ValueDeserializers\AliasValueDeserializer.cs:line 134
at YamlDotNet.Serialization.Deserializer.Deserialize(IParser parser, Type type) in C:\projects\yamldotnet\YamlDotNet\Serialization\Deserializer.cs:line 315
at YamlDotNet.Serialization.Deserializer.Deserialize[T](TextReader input) in C:\projects\yamldotnet\YamlDotNet\Serialization\Deserializer.cs:line 257
at Ebys.CleanFolders.Library.ConfigurationReader.Read[T](String configurationFile) in E:\WorkingGit\bitbucket\CleanFolders\Ebys.CleanFolders.Library\ConfigurationReader.cs:line 21
at Ebys.CleanFolders.ConsoleUi.Program.Main(String[] args) in E:\WorkingGit\bitbucket\CleanFolders\Ebys.CleanFolders\Program.cs:line 27
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
HResult=-2147467262
Message=Invalid cast from 'System.String' to 'Ebys.CleanFolders.Library.FolderPreferences'.
Source=mscorlib
StackTrace:
at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)
at System.String.System.IConvertible.ToType(Type type, IFormatProvider provider)
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at YamlDotNet.Serialization.Utilities.TypeConverter.ChangeType(Object value, Type destinationType, CultureInfo culture) in C:\projects\yamldotnet\YamlDotNet\Serialization\Utilities\TypeConverter.cs:line 128
at YamlDotNet.Serialization.NodeDeserializers.ScalarNodeDeserializer.YamlDotNet.Serialization.INodeDeserializer.Deserialize(IParser parser, Type expectedType, Func`3 nestedObjectDeserializer, Object& value) in C:\projects\yamldotnet\YamlDotNet\Serialization\NodeDeserializers\ScalarNodeDeserializer.cs:line 96
at YamlDotNet.Serialization.ValueDeserializers.NodeValueDeserializer.DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer) in C:\projects\yamldotnet\YamlDotNet\Serialization\ValueDeserializers\NodeValueDeserializer.cs:line 60
InnerException:
知道我做错了什么吗?
已编辑
GVim 中 Hexa 视图中的文件。
我猜你的文件开头有额外的内容,这些内容被解释为包含单个字符串的初始文档,因此是异常。检查以下 fiddle,它使用您的代码并按预期工作:
https://dotnetfiddle.net/tilGHT
然后与这个比较,在文档开始之前添加了额外的文本:
https://dotnetfiddle.net/d72Jut
您可以尝试删除开头的 ---
,因为无论如何它都是可选的。
问题是您正在创建 StringReader
,它是针对您指定的字符串的 reader,而不是针对文件的 reader。您需要使用 File.OpenText
或类似的 API 从文件中读取:
public FolderPreferences Read(string configurationFile)
{
using (var input = File.OpenText(configurationFile))
{
var deserializerBuilder = new DeserializerBuilder().WithNamingConvention(new CamelCaseNamingConvention());
var deserializer = deserializerBuilder.Build();
var result = deserializer.Deserialize<FolderPreferences>(input);
return result;
}
}