0

I am using the Json namespace provided by .NET, not the Newtonsoft one. I have a piece of code:

            string text;
            text = File.ReadAllText(EntityDirectory + @"\Json\AbilityTemplates.json");
            foreach (AbilityTemplate template in JsonSerializer.Deserialize<List<AbilityTemplate>>(text)) {
                loaderInterface.AddAbilityTemplate(template);
            }

When the code run to the JsonSerializer.Deserialize, an execption was thrown.

System.Text.Json.JsonException: 'The JSON value could not be converted to System.Collections.Generic.List`1[Enigma.Game.AbilityTemplate]. Path: $ | LineNumber: 0 | BytePositionInLine: 1.'

This is the Json text that I have:

{
  {
    "ID": "StandardShot",
    "Price": "10",
    "Size": "1",
    "Rarity": "Common",
    "AbilityEffectFactory": "StandardShotEffectFactory"
  },
  {
    "ID": "SelfDestructSingleDamage",
    "Price": "0",
    "Size": "0",
    "Rarity": "NotForPlayer",
    "AbilityEffectFactory": "SelfDestructSingleDamageEffectFactory"
  }
}

I wrote a constructor with JsonConstructor Attribute, but seems like it didn't work:

        public AbilityTemplate(string id, int price, int size, Rarity rarity, AbilityEffectFactory abilityEffectFactory) {
            Id = id;
            Price = price;
            Size = size;
            Rarity = rarity;
            AbilityEffectFactory = abilityEffectFactory;
        }

        [JsonConstructor]
        public AbilityTemplate(string id, int price, int size, Rarity rarity, string abilityEffectFactory) : this(id, price, size, rarity, AbilityEffectFactory.Dictionary[abilityEffectFactory]) { }

Rarity is an enum type.

————————Edit——————————

I change the brackets from {} to [],and also made the fields in json text exactly match the parameters name, but it still didn't work. This is my new Json text:

[
  {
    "id": "StandardShot",
    "price": "10",
    "size": "1",
    "rarity": "Common",
    "abilityEffectFactory": "StandardShotEffectFactory"
  },
  {
    "id": "SelfDestructSingleDamage",
    "price": "0",
    "size": "0",
    "rarity": "NotForPlayer",
    "abilityEffectFactory": "SelfDestructSingleDamageEffectFactory"
  }
]

System.InvalidOperationException: 'Each parameter in the deserialization constructor on type 'Enigma.Game.AbilityTemplate' must bind to an object property or field on deserialization. Each parameter name must match with a property or field on the object. The match can be case-insensitive.'

3
  • 2
    Replace the first pair of '{ }' with "[ ]" To indicate, that you have a List/Array Commented Nov 17, 2021 at 8:41
  • I think you're done now. Simply remove the constructor tagged with JsonConstructor attribute and you're good to go. Commented Nov 18, 2021 at 15:03
  • Might you please edit your question to share a minimal reproducible example? Do note that System.Text.Json is case-sensitive by default; if your property name is Id you may need to set JsonSerializerOptions.PropertyNameCaseInsensitive = true as shown in JsonSerializer.Deserialize fails. You also need tp use JsonStringEnumConverter to serialize an enum as a string, see this answer to ASP.NET MVC Core API Serialize Enums to String. Commented Dec 13, 2021 at 17:04

1 Answer 1

-1

The first problem is in your JSON value. You should start and end an array in your JSON file with [ ] instead of { }. To check the validity of your JSON file you can use an online tools such as https://codebeautify.org/jsonviewer. This website is good for validating and editing JSON files.

After changing your JSON file you can deserialize it very easily. First, you should make a model with the same properties as your JSON file. Be careful, the type of properties should match the ones in JSON file. All keys in your sample JSON file are strings.

For this sample file you should make a model as below:

public class weatherForecastModel
    {
        public string ID { get; set; }
        public string Price { get; set; }
        public string Size { get; set; }
        public string Rarity { get; set; }
        public string AbilityEffectFactory { get; set; }
    }

After that, you can deserialize your JSON to your model with one line of code:

var jsonString = File.ReadAllText(EntityDirectory + @"\Json\AbilityTemplates.json");
var weatherForecast = JsonSerializer.Deserialize<List<weatherForecastModel>>(jsonString);

or, if you use Newtonsoft, you can use :

var res = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString);
Sign up to request clarification or add additional context in comments.

2 Comments

But i want to use the JsonConstructor inorder to get rid of an unnecessary aditional class.
Ok good. but I think my solution its more readable and simple. I always tray to solve problems with simple solution by attention to KISS principle :) en.wikipedia.org/wiki/KISS_principle

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.