0

I'm trying to read the following JSON from a file using JSON.NET.

{
    "SendTelemetry": true
}

However, I'm having some issues with parsing the data. Here's what I have so far.

public class SettingsStore
{
    [JsonProperty]
    public bool SendTelemetry { get; set; }

    public dynamic ReadJsonFile(string filePath)
    {
        if (string.IsNullOrEmpty(filePath)) { throw new ArgumentNullException("filePath"); }

        if (!File.Exists(filePath))
        {
            throw new FileNotFoundException(string.Format(@"JSON settings file not found at [{0}]", filePath));
        }

        return JsonConvert.DeserializeObject(File.ReadAllText(filePath));
    }

    public void WriteJsonFile(string fileDirectory, string filePath, string json)
    {
        if (!Directory.Exists(fileDirectory))
        {
            Directory.CreateDirectory(fileDirectory);
        }

        File.WriteAllText(filePath, json);
    }
}

var rootDir = Environment.ExpandEnvironmentVariables(@"%localappdata%\LigerShark\SideWaffle\");
var filePath = Path.Combine(rootDir, "SideWaffle-Settings.json");
settings = new SettingsStore();
string json = settings.ReadJsonFile(filePath);
bool telemetry = JsonConvert.DeserializeObject<SettingsStore>(json.ToString()).SendTelemetry;

When it gets to the point of deserializing the json I get the error Cannot implicitly convert type 'Newtonsoft.Json.Linq.JToken' to 'string'. An explicit conversion exists (are you missing a cast?) I've been going through the JSON.NET documentation but I know I'm missing something. Can someone please help point me in the right direction?

3 Answers 3

1

The reason you are having an issue is with you de serialization returning a JToken as you have not casted your result.

I would suggest changing your methods slightly to have the ReadJsonFile return an instance of SettingsStore and this method being static (as no need for an instance if you are creating a new object).

Something like this looks like it should do the trick.

public class SettingsStore
{
    [JsonProperty]
    public bool SendTelemetry { get; set; }

    public static SettingsStore ReadJsonFile(string filePath)
    {
        if (string.IsNullOrEmpty(filePath)) { throw new ArgumentNullException("filePath"); }

        if (!File.Exists(filePath))
        {
            throw new FileNotFoundException(string.Format(@"JSON settings file not found at [{0}]", filePath));
        }

        return JsonConvert.DeserializeObject<SettingsStore>(File.ReadAllText(filePath));
    }

    public void WriteJsonFile(string fileDirectory, string filePath, string json)
    {
        if (!Directory.Exists(fileDirectory))
        {
            Directory.CreateDirectory(fileDirectory);
        }

        File.WriteAllText(filePath, json);
    }
}

This is easily called in one line using.

var settings = SettingsStore.ReadJsonFile("....");
Sign up to request clarification or add additional context in comments.

Comments

1

It looks like you're calling JsonConvert.DeserializeObject() twice - once in ReadJsonFile() and once in the code at the bottom. You should only need to call it once, so I'd get rid of the call to settings.ReadJsonFile() and instead do:

bool telemetry = JsonConvert.DeserializeObject<SettingsStore>(File.ReadAllText(filePath)).SendTelemetry;

(of course, you can move that into a method if you'd prefer so you can add back the checks on filePath)

Comments

1

ReadJsonFile is returning a JToken, as you're already deserializing the object.

Change your code to this:

public class SettingsStore
{
    [JsonProperty]
    public bool SendTelemetry { get; set; }

    public static SettingsStore ReadJsonFile(string filePath)
    {
        if (string.IsNullOrEmpty(filePath)) { throw new ArgumentNullException("filePath"); }

        if (!File.Exists(filePath))
        {
            throw new FileNotFoundException(string.Format(@"JSON settings file not found at [{0}]", filePath));
        }

        return JsonConvert.DeserializeObject<SettingsStore>(File.ReadAllText(filePath));
    }

    public void WriteJsonFile(string fileDirectory, string filePath, string json)
    {
        if (!Directory.Exists(fileDirectory))
        {
            Directory.CreateDirectory(fileDirectory);
        }

        File.WriteAllText(filePath, json);
    }
}

And then:

var rootDir = Environment.ExpandEnvironmentVariables(@"%localappdata%\LigerShark\SideWaffle\");
var filePath = Path.Combine(rootDir, "SideWaffle-Settings.json");
var settingsStore = SettingsStore.ReadJsonFile(filePath);
bool telemetry = settingsStore.SendTelemetry;

Comments

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.