Search code examples
c#asp.net-mvcrazorasp.net-core-2.2base-class

Working with a base class and have classes that inherite from it


I have a base class :

public class BaseClass
{
    public string Name { get; set; }
    public string LastName { get; set; }
}

Class that inherite from BaseClass :

public class InheriteClass : BaseClass
{
    public string MyProperty { get; set; }
}

So the first view you need to fill in your "Name" and "LastName", then click next and you go to another view with more fields.

But when I click in this view on the "Submit" button the properties "Name" and LastName" are null...

First page "Next" button :

    public IActionResult GoToCategoryView(BaseClass baseClass)
    {
        return RedirectToAction("NextView", baseClass);
    }

The next view has :

@model InheritanceClass

And when I click the "Submit" button :

    public IActionResult SubmitThis(InheritanceClass inheritanceClass )
    {
        var testClass = new testClass
        {
            Name = inheritanceClass.Name,
            LastName = inheritanceClass.LastName,
            MyProperty = inheritanceClass.MyProperty
        };

        return View(testClass);
    }

UPDATE With clearer sample. In the above sample "Name" and "LastName" are null.


Solution

  • Invoking an action via a request is not the same thing as just calling a method on a class. In the latter situation, you already have an InheritanceClass in memory, and you're simply upcasting it to BaseClass. Then, of course, later you can downcast it back to an InheritanceClass, because that's what it is.

    For an action, the param is being provided from the request, which is just unstructured, unbound data. A modelbinder is employed to attempt to "bind" that data to an actual structured type. In order to do that, it looks at the type of the param and instantiates that type (i.e. BaseClass). Then, it maps data over from the request on to appropriate properties on that class instance. Importantly, though, BaseClass doesn't have a MyProperty property, so the modelbinder will discard that value. What you have at the end is just a BaseClass instance, because that's the type of the param. You can downcast to InheritanceClass, if you like, but any properties specific to InheritanceClass will be null or default, because they don't exist on BaseClass.

    Long and short, you can't bind to base classes in actions. Anything not on the base class will be discarded. If you need InheritanceClass, then you must bind to InheritanceClass.