Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to serialize again? #19

Closed
Bluscream opened this issue Apr 7, 2020 · 9 comments
Closed

How to serialize again? #19

Bluscream opened this issue Apr 7, 2020 · 9 comments

Comments

@Bluscream
Copy link

Bluscream commented Apr 7, 2020

i have a public List<Mount> Mounts { get; set; } and i want to write that back to a vdf file, how would i do that? i believe it's something with VdfConvert.Serialize() but that requires a VToken, how do i get that?

@shravan2x
Copy link
Owner

shravan2x commented May 16, 2020

I'll address each part of your question separately:

  1. Why doesn't Vdf.NET support serializing generic objects like Json.NET does?

Ideally it would. However, this is a fairly complex feature and serialization is generally a less common use case than deserialization. So it hasn't been implemented so far. However, it's a planned feature for the long term. In addition, there's the hacky solution as shown in part 3.

  1. What is a VToken? How do I get one?

VTokens are analogous to JTokens from Json.NET. Many types in Vdf.NET are intentionally similar to Json.NET to make the library feel intuitive. To understand this type more, I'd suggest reading about JTokens since that library has a lot more documentation.

In short, a VToken is the base type of all Vdf.NET containers like VObject, VProperty, and VValue. So to serialize some data, you need to construct a VDF container and pass it to VdfConvert.Serialize(). Alternatively, jump to part 3 for the hackier, but easier solution.

Since VDF files always have a VProperty as the root, you'll want to construct a VProperty with a key and a VObject as its value. See the methods of VObject in the source. You'll likely want to use the Add(string key, VToken value) method to add properties. An example is:

VObject rootValue = new VObject();
rootValue.Add("hello", new VValue("world"));
rootValue.Add("hello2", new VValue("world2"));
Console.WriteLine(VdfConvert.Serialize(new VProperty("RootName", rootValue)));

// Prints:
// "RootName"
// {
//         "hello" "world"
//         "hello2" "world2"
// }
  1. Is there an easy way to serialize generic objects?

Yes, using the Gameloop.Vdf.JsonConverter package. You could simply do:

Mount someMount = new Mount { Hello = "world", Hello2 = "world2" };
VObject rootValue = JObject.FromObject(someMount).ToVdf();
Console.WriteLine(VdfConvert.Serialize(new VProperty("RootName", rootValue)));

// Prints the same output as above.

This solution is a little simpler in that you can use models again, however, it requires an intermediate conversion to JObject.

@Bluscream
Copy link
Author

VObject rootValue = JObject.FromObject(someMount).ToVdf();
Console.WriteLine(VdfConvert.Serialize(new VProperty("RootName", rootValue)));

How about a list?

@shravan2x
Copy link
Owner

shravan2x commented May 16, 2020

VDF doesn't support lists. The Gameloop.Vdf.JsonConverter package addresses the issue of lists in the FAQ. The code itself is the same - JArray.FromObject().

@Bluscream
Copy link
Author

Bluscream commented May 16, 2020

So i would basically do

List<Mount> someMounts = new List<Mount>(mount1, mount2);
VObject rootValue = JObject.FromObject(someMounts ).ToVdf();
Console.WriteLine(VdfConvert.Serialize(new VProperty("RootName", rootValue)));

? When i try it i get
image

@shravan2x
Copy link
Owner

I strongly suggest you read how Json.NET works and how to obtain JTokens from objects/lists. The Gameloop.Vdf.JsonConverter package simply takes a JToken and converts it to a VToken via the ToVdf() extension. Some relevant links:

@Bluscream
Copy link
Author

Bluscream commented May 16, 2020

This stuff is becoming increasingly more difficult. I already hated documents, elements and nodes from C#'s XML crap. Just to make this clear in my head now, are you saying that it's impossible to get the VDF file representation from a seemingly "random" class? Or are you just not willing to show the steps needed because it gets too complicated?

Don't get my wrong, i appreciate all the effort in making a lib that helps with this but i'm just used of the simplicity of throwing literally anything at the JSONparser and it just spits out the result. not more than one line required

I'm so glad there are smart people on the C# discord that help with more generic problems :3

@shravan2x
Copy link
Owner

are you saying that it's impossible to get the VDF file representation from a seemingly "random" class? Or are you just not willing to show the steps needed?

There may exist some single-line way to get the VDF representation of a generic object, but I don't know it. If it does exist, you'll find it by learning more about the FromObject method provided by Json.NET. For example, there may be a FromObject you could call from JArray or JToken.

I'm saying that I can only provide you with the resources to help you do what you want. I can't write your code for you.

Don't get my wrong, i appreciate all the effort in making a lib that helps with this but i'm just used of the simplicity of throwing literally anything at the JSONparser and it just spits out the result. not more than one line required

I'm confident there doesn't exist any library to do this for you. You'll either have to write it yourself or understand how to use an existing library.

@Bluscream
Copy link
Author

There may exist some single-line way to get the VDF representation of a generic object, but I don't know it. If it does exist, you'll find it by learning more about the FromObject method provided by Json.NET. For example, there may be a FromObject you could call from JArray or JToken.

Damn, that's too sad. I'll probably try to hack something together with a stringbuilder until a usable way is found, thanks

@shravan2x
Copy link
Owner

I'm closing this issue for now since adding support for serializing generic objects is not a planned feature. One alternative I've since learned is to obtain a JToken via JToken.FromObject and to then call .ToVdf() on it. Feel free to reopen if you need more help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants