Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ArgumentNullException: Value cannot be null. Parameter name: constructor

I'm building a ASP.NET 5 MVC application, using EF 7. I've got three models: The Book class:

public class Book : IBook<MangaChapter>, IHasThumbnail, IBugChecker
    {
        public Book()
        {
            Chapters = new List<MangaChapter>();
        }

        [Key]
        public int ID { get; set; }


        [Required]
        public string Title { get; set; }

        [Required]
        [DataType(DataType.MultilineText)]
        public string Description { get; set; }

        public string ThumbnailPath { get; set; }

        public virtual IList<Chapter> Chapters { get; set; }
}

The chapter class:

public class MangaChapter : IChapter<MangaBook>, IHasThumbnail
    {
        public MangaChapter()
        {
            PagesPath = new List<Path>();
        }

        [Key]
        public int ID { get; set; }

        [Required]
        public string Title { get; set; }

        public string ThumbnailPath { get; set; }

        public IList<Path> PagesPath { get; set; }

        public int BookID { get; set; }
        public MangaBook Book { get; set; }
    }
}

and the path class, that I introduced just to store a list in EF

public class Path
    {
        public Path(string s) { P = s; }

        public int ID { get; set; }

        public string P { get; set; }

        public int MangaChapterID { get; set; }

        public MangaChapter MangaChapter { get; set; }

        public static implicit operator Path(string s)
        {
            return new Path(s);
        }

        public static implicit operator string(Path s)
        { return s.P; }
    }

the Problem is when I try to access the database using myDbContext, in this way:

var list = _db.Paths.ToList();

I get a Exception: ArgumentNullException: Value cannot be null. Parameter name: constructor. I've tried to access it in different ways, but always ended up with that exception.

P.S. the source code for the application is entirely on GitHub

like image 627
WizardOfMenlo Avatar asked Mar 16 '23 01:03

WizardOfMenlo


1 Answers

You need a default constructor on the Path object:

public Path()
{
}

Entity Framework (much like all the JSON Serializers, XML Serializers, and other serailizers I can think of) requires a default constructor on all objects in order to properly serialize/save and deserailize/load it.

This question answers it pretty well:

No parameterless constructor defined for type of 'System.String' during JSON deserialization

Basically, the Serailizer/Deserailizer needs to create an empty object to assign values to it. It is not capable of making a complex decision of deciding what constructor to use. Yes, an argument could be made that it could infer what properties go into the constructor by the names, but in your situation it cannot even do that (which it wouldn't even try to, but that's beyond my point). The parameter in your constructor would is called s, but you have no property with which to match up s. (Again, this is not anything it would try, but if it could it would fail.)

Basically, if you plan on doing any serialization/deserialization/database saving/database loading of the type, you need to implement a default constructor, even if all it does is create a completely emptied object.

like image 70
Der Kommissar Avatar answered Mar 26 '23 01:03

Der Kommissar