简体   繁体   中英

JsonConvert.DeserializeObject() throwing System.ArgumentNullException: 'Path cannot be null. Parameter name: path' exception. Why?

My class structure is as follows:

class AppDetails
{
    public String companyName { get; set; }
    public String applicationName { get; set; }
    public String version { get; set; }
    public List<File_> fileObjectList { get; set; }

    public AppDetails(String cName, String aName, String v)
    {
        companyName = cName;
        applicationName = aName;
        version = v;
    }
}

class File_
{
    public String filePath { get; set; }
    public FileRecord fileRecord { get; set; }
    public File_(String parent_, String filepath_, Boolean Ignored)
    {
        filePath = filepath_;
        fileRecord = new FileRecord(parent_ + filePath, Ignored);
    }
}

class FileRecord
{
    public Boolean ignored { get; set; }
    public String MD5Checksum { get; set; }
    public int version { get; set; }

    public FileRecord(String filePath, Boolean ignored_)
    {
        ignored = ignored_;
        if (ignored)
        {
            MD5Checksum = null;
        }
        else
        {
            MD5Checksum = CalculateMD5(filePath);
            version = 0;
        }
    }

    static string CalculateMD5(string filePath)
    {
        var md5 = MD5.Create();
        var stream = File.OpenRead(filePath);
        var hash = md5.ComputeHash((System.IO.Stream)stream);
        return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();

    }

}

I generated Json file using these classes. But when I try to initialize an object with the said JSON file, it throws System.ArgumentNullException: 'Path cannot be null. Parameter name: path' exception. This is the function that is supposed to return the object.

AppDetails ReadJsonFile()
    {
        using (StreamReader r = File.OpenText(parent + "\\AllFilesList.json"))
        {
            string json = r.ReadToEnd();
            var result = JsonConvert.DeserializeObject<AppDetails>(json);
            return result;
        }
    }

I tried generating the classes from JSON using online class generators and it matches my class structure. Exception is thrown on this line:

var result = JsonConvert.DeserializeObject<AppDetails>(json);

Json string is getting loaded with the content from the file just fine(as can be seen from the watch). I couldn't find anything about Path issues related to JsonConvert.DeserializeObject. Most previous questions seems to be related to value errors.

EDIT: Serialization Code

void JsonWriter(AppDetails appDetails, String filename)
    {
        string path = parent + "\\" + filename + ".json";
        File.Delete(path);
        string json = JsonConvert.SerializeObject(appDetails);
        using (var tw = new StreamWriter(path, true))
        {
            tw.WriteLine(json.ToString());
            tw.Close();
        }
    }

Sample Json File:

{"companyName":"Home","applicationName":"Test","version":"V5.0.1","fileObjectList":[{"filePath":"\\bug-tracker.exe","fileRecord":{"ignored":false,"MD5Checksum":"a5254a813a040b429f2288df737a8b9f","version":0}},{"filePath":"\\bug-tracker.exe.config","fileRecord":{"ignored":false,"MD5Checksum":"e5c3e9137dc8fadb57dfc27b0ba6855c","version":0}},{"filePath":"\\bug-tracker.pdb","fileRecord":{"ignored":false,"MD5Checksum":"9a9dfda29dcaacae82cba7bd7aa97ffa","version":0}},{"filePath":"\\Caliburn.Micro.dll","fileRecord":{"ignored":false,"MD5Checksum":"aa5f96c02b08d9b33322f3024058dd91","version":0}},{"filePath":"\\Caliburn.Micro.Platform.Core.dll","fileRecord":{"ignored":false,"MD5Checksum":"ab7867bd44b59879a59b5cb968e15668","version":0}},{"filePath":"\\Caliburn.Micro.Platform.Core.xml","fileRecord":{"ignored":false,"MD5Checksum":"cdfcbbf70a9a62b92e82a953ab9e7e30","version":0}},{"filePath":"\\Caliburn.Micro.Platform.dll","fileRecord":{"ignored":false,"MD5Checksum":"a52bdecbc1b7625cb13c9385fad4231b","version":0}},{"filePath":"\\Caliburn.Micro.Platform.xml","fileRecord":{"ignored":false,"MD5Checksum":"09f258a3aeca7285355d82a66dda2176","version":0}},{"filePath":"\\Caliburn.Micro.xml","fileRecord":{"ignored":false,"MD5Checksum":"c87ec582a4bfcf2e79e517c689441def","version":0}},{"filePath":"\\MaterialDesignColors.dll","fileRecord":{"ignored":false,"MD5Checksum":"ad729352a9088b889cc0c4dc7542dcb6","version":0}},{"filePath":"\\MaterialDesignColors.pdb","fileRecord":{"ignored":false,"MD5Checksum":"7ba70b23e22db9ac155e190860d9a5ec","version":0}},{"filePath":"\\MaterialDesignThemes.Wpf.dll","fileRecord":{"ignored":false,"MD5Checksum":"e4c790d3af41620dc5ad513ae7fcadac","version":0}},{"filePath":"\\MaterialDesignThemes.Wpf.pdb","fileRecord":{"ignored":false,"MD5Checksum":"f8113c8ea54896b8150db8e7ebd506ef","version":0}},{"filePath":"\\MaterialDesignThemes.Wpf.xml","fileRecord":{"ignored":false,"MD5Checksum":"49717f8130b7529ee51fb6bc13f79aa4","version":0}},{"filePath":"\\ShowMeTheXAML.dll","fileRecord":{"ignored":false,"MD5Checksum":"040b9e80820553a55f13ac19c2036367","version":0}},{"filePath":"\\System.Windows.Interactivity.dll","fileRecord":{"ignored":false,"MD5Checksum":"580244bc805220253a87196913eb3e5e","version":0}}]}

Edit 2: Json String from watch

"{\"companyName\":\"Home\",\"applicationName\":\"Test\",\"version\":\"V5.0.1\",\"fileObjectList\":[{\"filePath\":\"\\\\bug-tracker.exe\",\"fileRecord\":{\"ignored\":false,\"MD5Checksum\":\"a5254a813a040b429f2288df737a8b9f\",\"version\":0}},{\"filePath\":\"\\\\bug-tracker.exe.config\",\"fileRecord\":{\"ignored\":false,\"MD5Checksum\":\"e5c3e9137dc8fadb57dfc27b0ba6855c\",\"version\":0}},{\"filePath\":\"\\\\bug-tracker.pdb\",\"fileRecord\":{\"ignored\":false,\"MD5Checksum\":\"9a9dfda29dcaacae82cba7bd7aa97ffa\",\"version\":0}},{\"filePath\":\"\\\\Caliburn.Micro.dll\",\"fileRecord\":{\"ignored\":false,\"MD5Checksum\":\"aa5f96c02b08d9b33322f3024058dd91\",\"version\":0}},{\"filePath\":\"\\\\Caliburn.Micro.Platform.Core.dll\",\"fileRecord\":{\"ignored\":false,\"MD5Checksum\":\"ab7867bd44b59879a59b5cb968e15668\",\"version\":0}},{\"filePath\":\"\\\\Caliburn.Micro.Platform.Core.xml\",\"fileRecord\":{\"ignored\":false,\"MD5Checksum\":\"cdfcbbf70a9a62b92e82a953ab9e7e30\",\"version\":0}},{\"filePath\":\"\\\\Caliburn.Micro.Platform.dll\",\"fileRecord\":{\"ignored\":false,\"MD5Checksum\":\"a52bdecbc1b7625cb13c9385fad4231b\",\"version\":0}},{\"filePath\":\"\\\\Caliburn.Micro.Platform.xml\",\"fileRecord\":{\"ignored\":false,\"MD5Checksum\":\"09f258a3aeca7285355d82a66dda2176\",\"version\":0}},{\"filePath\":\"\\\\Caliburn.Micro.xml\",\"fileRecord\":{\"ignored\":false,\"MD5Checksum\":\"c87ec582a4bfcf2e79e517c689441def\",\"version\":0}},{\"filePath\":\"\\\\MaterialDesignColors.dll\",\"fileRecord\":{\"ignored\":false,\"MD5Checksum\":\"ad729352a9088b889cc0c4dc7542dcb6\",\"version\":0}},{\"filePath\":\"\\\\MaterialDesignColors.pdb\",\"fileRecord\":{\"ignored\":false,\"MD5Checksum\":\"7ba70b23e22db9ac155e190860d9a5ec\",\"version\":0}},{\"filePath\":\"\\\\MaterialDesignThemes.Wpf.dll\",\"fileRecord\":{\"ignored\":false,\"MD5Checksum\":\"e4c790d3af41620dc5ad513ae7fcadac\",\"version\":0}},{\"filePath\":\"\\\\MaterialDesignThemes.Wpf.pdb\",\"fileRecord\":{\"ignored\":false,\"MD5Checksum\":\"f8113c8ea54896b8150db8e7ebd506ef\",\"version\":0}},{\"filePath\":\"\\\\MaterialDesignThemes.Wpf.xml\",\"fileRecord\":{\"ignored\":false,\"MD5Checksum\":\"49717f8130b7529ee51fb6bc13f79aa4\",\"version\":0}},{\"filePath\":\"\\\\ShowMeTheXAML.dll\",\"fileRecord\":{\"ignored\":false,\"MD5Checksum\":\"040b9e80820553a55f13ac19c2036367\",\"version\":0}},{\"filePath\":\"\\\\System.Windows.Interactivity.dll\",\"fileRecord\":{\"ignored\":false,\"MD5Checksum\":\"580244bc805220253a87196913eb3e5e\",\"version\":0}}]}\r\n"

The actual issue is that you have the parameters in your constructor:

public FileRecord(String filePath, Boolean ignored_)

And JsonConvert puts there default values (null, false) which triggers the code:

else
{
    MD5Checksum = CalculateMD5(filePath);
    version = 0;
}

Which in its turn tries to read from a file using null path parameter:

static string CalculateMD5(string filePath)
    {
        var md5 = MD5.Create();
        var stream = File.OpenRead(filePath); // <- HERE!!!!
        var hash = md5.ComputeHash((System.IO.Stream)stream);
        return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();

    }

I see there two solutions

  • Create parameterless constructors where init everything as you need or call the constructor with parameters using :this() with defaults:

    public FileRecord() : this(null, true) { }

  • Rename properties to match parameter names, like:

     public bool Ignored { get; set; } public FileRecord(string filePath, bool ignored) { this.Ingnoerd = ignored; .... }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM