C
C#2y ago
malkav

✅ Parse .md like .json in C# class

Does anyone know how I can parse a "settings markdown" file into a C# class, like I could do with newtonsoft for JSON files? Example: I have this "settings.md" file
---
Title: myTitle
first_object_settings:
title: some_title
subtitle: some-subtitle
button_content: my button content
second_object_header:
title: another_title
subtitle: another_subtitle
second_object_settings:
url: some.url.here
image: path/or/url/to/image
---
---
Title: myTitle
first_object_settings:
title: some_title
subtitle: some-subtitle
button_content: my button content
second_object_header:
title: another_title
subtitle: another_subtitle
second_object_settings:
url: some.url.here
image: path/or/url/to/image
---
How can I parse this into a C# class like this:
public class Setting
{
public string Title {get;set;}
public FirstObject FirstObject {get;set;}
public Header SecondObjectHeader {get;set;}
public SecondObject SecondObjectContent {get;set;}
//...
}

public class Header
{
public string Title {get;set;}
public string Subtitle {get;set;}
}

public class SecondObject
{
public string Url {get;set;}
public string Image {get;set;}
}
public class Setting
{
public string Title {get;set;}
public FirstObject FirstObject {get;set;}
public Header SecondObjectHeader {get;set;}
public SecondObject SecondObjectContent {get;set;}
//...
}

public class Header
{
public string Title {get;set;}
public string Subtitle {get;set;}
}

public class SecondObject
{
public string Url {get;set;}
public string Image {get;set;}
}
(and following the same structure any number of other objects) I'm using DecapCMS in my Blazor project, but DecapCMS creates markdown files that I want to render the content into my blazor project The "settings" are also created in markdown, and regular content is written under the "header" from the markdown (blog example)
---
title: Blog Title
date: Creation Date
tags: Array of Tags
---
## Blog
some actual blog content written here like regular markdown
---
title: Blog Title
date: Creation Date
tags: Array of Tags
---
## Blog
some actual blog content written here like regular markdown
I'd want to parse that into a C# class too 😅 (and the regular content I can parse into HTML without issue)
71 Replies
malkav
malkavOP2y ago
This is what I came up wit now, and it feel clunky 😅
public static T ParseSettings<T>(string path) where T : new()
{
if (!path.EndsWith(".md"))
throw new Exception("Settings can only be parsed of markdown files");
List<string> preFile = File.ReadAllLines(path).ToList();
preFile.RemoveAt(0);
preFile.RemoveRange(
preFile.LastIndexOf("---"),
preFile.Count - (preFile.LastIndexOf("---") + 1)
);
preFile.RemoveAt(preFile.LastIndexOf("---");
string[] file = preFile.ToArray();

ISerializer serializer = new SerializerBuilder()
.WithNamingConvention(UnderscoredNamingConvention.Instance)
.Build();
string yml = serializer.Serialize(file);

IDeserializer deserializer = new DeserializerBuilder()
.WithNamingConvention(UnderscoredNamingConvention.Instance)
.Build();
return deserializer.Deserialize<T>(yml);
}
public static T ParseSettings<T>(string path) where T : new()
{
if (!path.EndsWith(".md"))
throw new Exception("Settings can only be parsed of markdown files");
List<string> preFile = File.ReadAllLines(path).ToList();
preFile.RemoveAt(0);
preFile.RemoveRange(
preFile.LastIndexOf("---"),
preFile.Count - (preFile.LastIndexOf("---") + 1)
);
preFile.RemoveAt(preFile.LastIndexOf("---");
string[] file = preFile.ToArray();

ISerializer serializer = new SerializerBuilder()
.WithNamingConvention(UnderscoredNamingConvention.Instance)
.Build();
string yml = serializer.Serialize(file);

IDeserializer deserializer = new DeserializerBuilder()
.WithNamingConvention(UnderscoredNamingConvention.Instance)
.Build();
return deserializer.Deserialize<T>(yml);
}
That's what I've been trying so far, to turn the .md file into a yaml file. But technically I should be creating .md file into yaml AND a content string. Or I have to turn it into JSON and parse it that way. But I don't know how to turn .md into JSON objects 😅 DecapCMS does not give me .json files sadly
Denis
Denis2y ago
Well it should be relatively easy to parse that settings file with a custom parser If the files strictly follow the example formatting, then you can get away with even not using RegEx and relying on Spans and simple string character checks Question is whether you wish to create a generic parser or a concrete one for the Settings and Header, etc. classes you've defined
malkav
malkavOP2y ago
I would like to create a generic parser However, I've noticed that I'll have to parse the file into a string first instead of using File.ReadAllLines() because of the Blazor WASM framework, a Directory or File. are not available, and will result in errors
Monsieur Wholesome
https://learn.microsoft.com/en-us/aspnet/core/blazor/file-uploads?view=aspnetcore-7.0&pivots=webassembly
foreach(var file in e.GetMultipleFiles(10))
{
using var reader = new StreamReader(file.OpenReadStream())

while(reader.ReadLine() is { } line)
{
// Do stuff with line
}
}
foreach(var file in e.GetMultipleFiles(10))
{
using var reader = new StreamReader(file.OpenReadStream())

while(reader.ReadLine() is { } line)
{
// Do stuff with line
}
}
ASP.NET Core Blazor file uploads
Learn how to upload files in Blazor with the InputFile component.
malkav
malkavOP2y ago
That's on uploaded from blazor itself. I"m looking for what DecapCMS has already uploaded and re-built using the git-pipeline. But it might give me some insight. However, I cannot seem to access a file directly, so I am currently bound to go to the URL (localhost:7052/uploads/fpsettings/settings.md for example) and read that as string. Given that I cannot seem to access File or Directory methods within a Blazor project, and these are not "Uploaded" files by the SWA itself
Monsieur Wholesome
I see Where exactly are the .md files located in your project
malkav
malkavOP2y ago
wwwroot/uploads
solution root
|-- Client <-- Blazor Project
|-- wwwroot
|-- uploads <-- Location of all DecapCMS uploaded .md files, with subfolders seperating the different setting
|-- fpsettings
|-- section_1
|-- section_2
|-- ...
|-- Client.Helpers
solution root
|-- Client <-- Blazor Project
|-- wwwroot
|-- uploads <-- Location of all DecapCMS uploaded .md files, with subfolders seperating the different setting
|-- fpsettings
|-- section_1
|-- section_2
|-- ...
|-- Client.Helpers
Monsieur Wholesome
So, does this happen at runtime, everytime someone visits your page, it reads the file/-s and creates all the necessary objects to render your thing?
malkav
malkavOP2y ago
what I've been trying in my index.razor
public override void OnInitializedAsync()
{
string fileLocation = Directory.GetCurrentDirectory() + "uploads/fpsettings/settings.md";
Client.Helpers.ParseMarkdown(fileLocation); // check my previous method
}
public override void OnInitializedAsync()
{
string fileLocation = Directory.GetCurrentDirectory() + "uploads/fpsettings/settings.md";
Client.Helpers.ParseMarkdown(fileLocation); // check my previous method
}
This breaks because the File.ReadAllLines() doesn't know where /uploads/fpsettings/settings.md is located, since the BlazorProject returns Diretory.GetCurrentDirectory() => returns "/" So I tried to do:
public override void OnInitializedAsync()
{
var file = File.ReadAllLines("/uploads/fpsettings/settings.md");
}
public override void OnInitializedAsync()
{
var file = File.ReadAllLines("/uploads/fpsettings/settings.md");
}
However this returns an error in console:
Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: Could not find a part of the path '/uploads/folder/settings.md'.
System.IO.DirectoryNotFoundException: Could not find a part of the path '/uploads/folder/settings.md'.
Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: Could not find a part of the path '/uploads/folder/settings.md'.
System.IO.DirectoryNotFoundException: Could not find a part of the path '/uploads/folder/settings.md'.
This is what I want it do do after parsing the .md files
Monsieur Wholesome
You will have to make an http request to the endpoint
using(HttpClient client = new HttpClient())
{
var response = await client.GetAsync("/uploads/fpsettings/settings.md", HttpCompletionOption.ResponseHeadersRead);

response.EnsureSuccessStatusCode();

using (var stream = await response.Content.ReadAsStreamAsync())
using (var streamReader = new StreamReader(stream))
{

}
}
using(HttpClient client = new HttpClient())
{
var response = await client.GetAsync("/uploads/fpsettings/settings.md", HttpCompletionOption.ResponseHeadersRead);

response.EnsureSuccessStatusCode();

using (var stream = await response.Content.ReadAsStreamAsync())
using (var streamReader = new StreamReader(stream))
{

}
}
malkav
malkavOP2y ago
Oh read as stream? Can I from there actually parse it? hang on tho, lemme see if this streamreader first
Monsieur Wholesome
StreamReader doesnt read the entire file into memory It reads line by line That's the memory efficient and performance critical approach to parsing text
malkav
malkavOP2y ago
Fair enough
Monsieur Wholesome
How big are your files circa?
malkav
malkavOP2y ago
in kb's? I don't know, but I think they'll rarely exceed 2mb if they even reach that high. They're blogs with references to uploaded images, or they are settings for various components Do I use streamReader.ReadToEndAsync() or should I pass the entire stream to the Parse method I'm writing?
Monsieur Wholesome
That's up to you 😆 I think your parser benefits from this more if you give it the whole stream
malkav
malkavOP2y ago
Fair enough How would you handle my parser different if it were you tho?
Monsieur Wholesome
What is this thing called within decap The .md file output thingy
malkav
malkavOP2y ago
what do you mean?
Monsieur Wholesome
Looking at https://decapcms.org/docs/intro/ rn Trynna find this .md output that it creates, which you mentioned
Overview | Decap CMS | Open-Source Content Management System
Open source content management for your Git workflow
Monsieur Wholesome
DecapCMS creates markdown files
malkav
malkavOP2y ago
I have created a yaml file with the settings and various collections you might be able to edit. After which it creates a markdown file in the specified folders.. I'm not sure what you mean with the "output thingy" the file I'm working on rn is called settings.md but later there might be [employee-name].md and [blog-title].md files too
Monsieur Wholesome
Ah, so you yourself write the .md files
malkav
malkavOP2y ago
yes, by a few "forms" that DecapCMS creates in the /admin/ route
malkav
malkavOP2y ago
yes those markdown files (in example) that is waht I want to parse into a C# class so my components can use the data in them
Monsieur Wholesome
public interface IBody
{
string Body { get; set; }
}
public class BlogPost : IBody
{
public string Body { get; set; }
}

public static T ParseSettings<T>(Stream stream)
where T : new(), IBody
{
using var reader = new StreamReader(stream);
var builder = new StringBuilder();

// Read and dump first line, as it's "---"
reader.ReadLine();
// Now read from the input line by line and store each in our stringbuilder, building up a yaml string, until the ending line ("---")
while(reader.ReadLine() is { } line && line != "---")
builder.AppendLine(reader.ReadLine());

var yamlPart = builder.ToString();
var bodyPart = reader.ReadToEnd(); // Everything after the "---" ending is called a "post body"

ISerializer serializer = new SerializerBuilder()
.WithNamingConvention(UnderscoredNamingConvention.Instance)
.Build();

string yml = serializer.Serialize(yamlPart ); // Dump it

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

var result = deserializer.Deserialize<T>(yml);
result.Body = bodyPart;

return result;
}
public interface IBody
{
string Body { get; set; }
}
public class BlogPost : IBody
{
public string Body { get; set; }
}

public static T ParseSettings<T>(Stream stream)
where T : new(), IBody
{
using var reader = new StreamReader(stream);
var builder = new StringBuilder();

// Read and dump first line, as it's "---"
reader.ReadLine();
// Now read from the input line by line and store each in our stringbuilder, building up a yaml string, until the ending line ("---")
while(reader.ReadLine() is { } line && line != "---")
builder.AppendLine(reader.ReadLine());

var yamlPart = builder.ToString();
var bodyPart = reader.ReadToEnd(); // Everything after the "---" ending is called a "post body"

ISerializer serializer = new SerializerBuilder()
.WithNamingConvention(UnderscoredNamingConvention.Instance)
.Build();

string yml = serializer.Serialize(yamlPart ); // Dump it

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

var result = deserializer.Deserialize<T>(yml);
result.Body = bodyPart;

return result;
}
My quick write up This made me realize, it's inevitable to load all contents of the file into memory, in order to work with it <:DFrido_HaHa:845975447971692635> But anywho, a streamreader prolly more performant
malkav
malkavOP2y ago
I guess? 😅 l Imma write this down, and see if I understand what's happning gimme a sec Shouldn't this change?
- builder.AppendLine(reader);
+ builder.AppendLine(reader.ReadLine);
- builder.AppendLine(reader);
+ builder.AppendLine(reader.ReadLine);
?
Monsieur Wholesome
Ah, yes Good catch Though it's a method, so add ()
malkav
malkavOP2y ago
Yea, true sorry 😅 misspell Also why dump the string yml = serializer.Serialize(yamlPart);? Oh, wait now I see, you're getting only the bdy body*
public static async Task<T> ParseSettingsAsync<T>(this Stream file, bool withBody = false)
where T : ISettings, new()
{
StringBuilder builder = new();
using StreamReader reader = new(file);
await reader.ReadLineAsync();

while (await reader.ReadLineAsync() is { } line && line != "---")
{
builder.AppendLine(await reader.ReadLineAsync());
}

string yamlPart = builder.ToString();
string bodyPart = await reader.ReadToEndAsync();

// Serializing the yaml data from the markdown file
ISerializer serializer = new SerializerBuilder()
.WithNamingConvention(UnderscoredNamingConvention.Instance)
.Build();
string yml = serializer.Serialize(yamlPart);

// and deserializing the data into an object Class defined by T
IDeserializer deserializer = new DeserializerBuilder()
.WithNamingConvention(UnderscoredNamingConvention.Instance)
.Build();
T result = deserializer.Deserialize<T>(yml);
if (withBody)
{
result.Body = bodyPart;
}

return result;
}
public static async Task<T> ParseSettingsAsync<T>(this Stream file, bool withBody = false)
where T : ISettings, new()
{
StringBuilder builder = new();
using StreamReader reader = new(file);
await reader.ReadLineAsync();

while (await reader.ReadLineAsync() is { } line && line != "---")
{
builder.AppendLine(await reader.ReadLineAsync());
}

string yamlPart = builder.ToString();
string bodyPart = await reader.ReadToEndAsync();

// Serializing the yaml data from the markdown file
ISerializer serializer = new SerializerBuilder()
.WithNamingConvention(UnderscoredNamingConvention.Instance)
.Build();
string yml = serializer.Serialize(yamlPart);

// and deserializing the data into an object Class defined by T
IDeserializer deserializer = new DeserializerBuilder()
.WithNamingConvention(UnderscoredNamingConvention.Instance)
.Build();
T result = deserializer.Deserialize<T>(yml);
if (withBody)
{
result.Body = bodyPart;
}

return result;
}
Is what I have now? just to make sure I can us this method for both a settings only file, as well as a settings with body file
Monsieur Wholesome
I mean I am not sure how much of a performance benefit turning the first two ReadLines into async has, as the whole Task-jazz has an overhead... For what? Reading and dumping 3 - 4 chars / bytes The body can prolly get extensive, there I get it
malkav
malkavOP2y ago
Fair, I just get the "this has an async overload" message, and press alt+enter 😅
Monsieur Wholesome
I cant really estimate the benefit / overhead here
malkav
malkavOP2y ago
this is my index.razor now 😅
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
using HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync("temporary/blog/url");
if (response.IsSuccessStatusCode)
{
string result = await response.Content.ReadAsStringAsync();
_blogs = JsonConvert.DeserializeObject<Blog[]>(result)!;
}


response = await client
.GetAsync("/uploads/fpsettings/settings.md");
await using Stream stream = await response.Content.ReadAsStreamAsync();
FrontPageSettings parsed = await stream
.ParseSettingsAsync<FrontPageSettings>();

Console.WriteLine(parsed.Title);
}
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
using HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync("temporary/blog/url");
if (response.IsSuccessStatusCode)
{
string result = await response.Content.ReadAsStringAsync();
_blogs = JsonConvert.DeserializeObject<Blog[]>(result)!;
}


response = await client
.GetAsync("/uploads/fpsettings/settings.md");
await using Stream stream = await response.Content.ReadAsStreamAsync();
FrontPageSettings parsed = await stream
.ParseSettingsAsync<FrontPageSettings>();

Console.WriteLine(parsed.Title);
}
Monsieur Wholesome
Wait, why are we serializing a string to string, just to deserialize it again
malkav
malkavOP2y ago
what a mess lol that's what you wrote, I'm still in process of understanding lol
Monsieur Wholesome
Thats what you wrote initially! I was building off your stuff
malkav
malkavOP2y ago
Ah, fair
Monsieur Wholesome
Looks good to me, only that you could use more vars, and less line LoveSmirkMothawait base.OnInitializedAsync(); not necessary Oh, you made the parsing an extension method <:DFrido_panik:875369065852571678>
malkav
malkavOP2y ago
yes is 😅 there is a login component that is handled with Graph in the base.OnInitialized() lol yea
malkav
malkavOP2y ago
I prefer static methods that way, dunno why change:
- string yamlPart = builder.ToString();
- string bodyPart = await reader.ReadToEndAsync();
- ISerializer serializer = new SerializerBuilder()
- .WithNamingConvention(UnderscoredNamingConvention.Instance)
- .Build();
- string yml = serializer.Serialize(yamlPart);

- IDeserializer deserializer = new DeserializerBuilder()
- .WithNamingConvention(UnderscoredNamingConvention.Instance)
- .Build();
- T result = deserializer.Deserialize<T>(yml);

+string bodyPart = await reader.ReadToEndAsync();
+ IDeserializer deserializer = new DeserializerBuilder()
+ .WithNamingConvention(UnderscoredNamingConvention.Instance)
+ .Build();
+ T result = deserializer.Deserialize<T>(builder.ToString());
- string yamlPart = builder.ToString();
- string bodyPart = await reader.ReadToEndAsync();
- ISerializer serializer = new SerializerBuilder()
- .WithNamingConvention(UnderscoredNamingConvention.Instance)
- .Build();
- string yml = serializer.Serialize(yamlPart);

- IDeserializer deserializer = new DeserializerBuilder()
- .WithNamingConvention(UnderscoredNamingConvention.Instance)
- .Build();
- T result = deserializer.Deserialize<T>(yml);

+string bodyPart = await reader.ReadToEndAsync();
+ IDeserializer deserializer = new DeserializerBuilder()
+ .WithNamingConvention(UnderscoredNamingConvention.Instance)
+ .Build();
+ T result = deserializer.Deserialize<T>(builder.ToString());
Monsieur Wholesome
Looks good to me
malkav
malkavOP2y ago
I'm running it lol
Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: An invalid request URI was provided. Either the request URI must be an absolute URI or BaseAddress must be set.
System.InvalidOperationException: An invalid request URI was provided. Either the request URI must be an absolute URI or BaseAddress must be set.
Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: An invalid request URI was provided. Either the request URI must be an absolute URI or BaseAddress must be set.
System.InvalidOperationException: An invalid request URI was provided. Either the request URI must be an absolute URI or BaseAddress must be set.
I have <base href="/"/> in my index.html guess I have to make it https://localhost:7052/uploads/fpsettings/settings.md
blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: Property 'subtitle' not found on type 'Client.Shared.Data.HeroSettings'.
(Line: 2, Col: 3, Idx: 17) - (Line: 2, Col: 11, Idx: 25): Property 'subtitle' not found on type 'Client.Shared.Data.HeroSettings'
blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: Property 'subtitle' not found on type 'Client.Shared.Data.HeroSettings'.
(Line: 2, Col: 3, Idx: 17) - (Line: 2, Col: 11, Idx: 25): Property 'subtitle' not found on type 'Client.Shared.Data.HeroSettings'
also that... eventhough I have a property public string SubTitle {get;set;} in there..
Monsieur Wholesome
Case sensitivity?
malkav
malkavOP2y ago
IDeserializer deserializer = new DeserializerBuilder()
.WithNamingConvention(PascalCaseNamingConvention.Instance)
.Build();
IDeserializer deserializer = new DeserializerBuilder()
.WithNamingConvention(PascalCaseNamingConvention.Instance)
.Build();
I have the PascalCaseNamingConvention tho
Monsieur Wholesome
oh wait, thats json Damn google, I specified yaml!
malkav
malkavOP2y ago
🤣 Maybe this doesn't work like the JSON parser, I've got the classes nested?
public class FrontPageSettings : ISettings
{
public string Title { get; set; }
public HeroSettings HeroSettings { get; set; }
public Header ClientHeader { get; set; }
public ClientItemData Clients { get; set; }
public Header ServicesHeader {get; set; }
public FeatureItem Services { get; set; }
public Header ExpertiseHeader { get; set; }
public FeatureItem Expertise { get; set; }
public Header AboutHeader { get; set; }
public SAbout About { get; set; }
public Header JobsHeader { get; set; }
public Job Jobs { get; set; }
public Header PartnershipsHeader { get; set; }
public SPartnerships Partnerships { get; set; }
public Header ContactHeader { get; set; }
public SContactInfo ContactInfo { get; set; }
public string? Body { get; set; }
}
public class FrontPageSettings : ISettings
{
public string Title { get; set; }
public HeroSettings HeroSettings { get; set; }
public Header ClientHeader { get; set; }
public ClientItemData Clients { get; set; }
public Header ServicesHeader {get; set; }
public FeatureItem Services { get; set; }
public Header ExpertiseHeader { get; set; }
public FeatureItem Expertise { get; set; }
public Header AboutHeader { get; set; }
public SAbout About { get; set; }
public Header JobsHeader { get; set; }
public Job Jobs { get; set; }
public Header PartnershipsHeader { get; set; }
public SPartnerships Partnerships { get; set; }
public Header ContactHeader { get; set; }
public SContactInfo ContactInfo { get; set; }
public string? Body { get; set; }
}
(imagine /// <summary> </summary> comments above each property)
Monsieur Wholesome
It should handle that
malkav
malkavOP2y ago
public class HeroSettings
{
public string Title { get; set; }
public string SubTitle { get; set; }
public string ButtonText { get; set; } = "neem contact op!";
}
public class HeroSettings
{
public string Title { get; set; }
public string SubTitle { get; set; }
public string ButtonText { get; set; } = "neem contact op!";
}
the markdown in question (example markdown)
---
title: FP Config
hero_settings:
title: my title
subtitle: test meuk
button_text: mail
client_header:
title: clients
subtitle: of us
clients: []
services_header:
title: services
subtitle: services
expertise_header:
title: expertise
subtitle: stuff
about_header:
title: about
subtitle: about
about:
- leadmct: true
mct: true
mvp: true
title: bryce
subtitle: manager
image: url.to.image.com
partnerships_header:
title: partnerships
subtitle: partners
---
---
title: FP Config
hero_settings:
title: my title
subtitle: test meuk
button_text: mail
client_header:
title: clients
subtitle: of us
clients: []
services_header:
title: services
subtitle: services
expertise_header:
title: expertise
subtitle: stuff
about_header:
title: about
subtitle: about
about:
- leadmct: true
mct: true
mvp: true
title: bryce
subtitle: manager
image: url.to.image.com
partnerships_header:
title: partnerships
subtitle: partners
---
that's actually all lol but it will increase in size a little when I do the genuine settings 😅 the idea is to use the parsed settings like this: <HeroBanner Title="@_settings.HeroSettings.Title" Description="@_settings.HeroSettings.SubTitle" ButtonContent="@_settings.HeroSettings.ButtonText"/> From either the index, or whichever page/component needs it (prolly by keeping components stupid, and calling back to parents)
Monsieur Wholesome
Yea
malkav
malkavOP2y ago
Do I make the class property lowercase all?
Monsieur Wholesome
nooooooooooooooooooo that disgustaang
malkav
malkavOP2y ago
Yea figured lol I need to figure a way to tell the deserializer that the parsed yaml is in underscore, and the target is in PascalCase 😅 THis is prolly why I serialized it first lol...
Monsieur Wholesome
I dont know yaml de-/serialization all that much, and I am glad about that So uh, you got this!
malkav
malkavOP2y ago
XD
Monsieur Wholesome
I hope you made a mistake there, and that's not the actual output
Monsieur Wholesome
<:DFrido_Hmm:704598915080781855>
malkav
malkavOP2y ago
how so? Hrm, that is the acutal output... that should all have - in front of them...
Monsieur Wholesome
A leading dash makes it an array, without a leading dash, its a property
malkav
malkavOP2y ago
- name: about
label: About Us
widget: list
fields:
- name: title
label: Name
widget: string
required: true
- name: subtitle
label: Functie
widget: string
required: true
- name: leadmct
label: Lead MCT
widget: boolean
required: false
default: false
- name: mct
label: MCT
widget: boolean
required: false
default: false
- name: mvp
label: MVP
widget: boolean
required: false
default: false
- name: image
label: Image
widget: image
required: true
- name: about
label: About Us
widget: list
fields:
- name: title
label: Name
widget: string
required: true
- name: subtitle
label: Functie
widget: string
required: true
- name: leadmct
label: Lead MCT
widget: boolean
required: false
default: false
- name: mct
label: MCT
widget: boolean
required: false
default: false
- name: mvp
label: MVP
widget: boolean
required: false
default: false
- name: image
label: Image
widget: image
required: true
Monsieur Wholesome
dies
malkav
malkavOP2y ago
I mean, this is the configuration file that states how they should be written why?
Monsieur Wholesome
or wait, it might be valid yaml yeah, this is where my yaml knowledge ends
malkav
malkavOP2y ago
lol okay 😅 but I think I found what can help tho
[YamlMember(Alias = "title")]
public string Title { get; set; }
[YamlMember(Alias = "title")]
public string Title { get; set; }
imma test it, but yea
Monsieur Wholesome
that will very likely work, though I was hoping for a better alternative Guess not
malkav
malkavOP2y ago
crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: Property 'hero_settings' not found on type 'Client.Shared.Data.FrontPageSettings'.
(Line: 1, Col: 1, Idx: 0) - (Line: 1, Col: 14, Idx: 13): Property 'hero_settings' not found on type 'Client.Shared.Data.FrontPageSettings'.
crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: Property 'hero_settings' not found on type 'Client.Shared.Data.FrontPageSettings'.
(Line: 1, Col: 1, Idx: 0) - (Line: 1, Col: 14, Idx: 13): Property 'hero_settings' not found on type 'Client.Shared.Data.FrontPageSettings'.
dafuq... Alias =>
Instructs the <see cref="T:YamlDotNet.Serialization.Deserializer" /> to use a different field name for serialization.
Instructs the <see cref="T:YamlDotNet.Serialization.Deserializer" /> to use a different field name for serialization.
So that should be right, innit? https://github.com/aaubry/YamlDotNet/wiki/Samples.DeserializeObjectGraph I'm going to take a break, but I really don't get this 😅
Monsieur Wholesome
Anything other than json is catsip
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
malkav
malkavOP2y ago
Since I'm going to change this up to parse .md files into .json files. I will close this post
Want results from more Discord servers?
Add your server