1

I'm starting to working on ASP.NET using MVC. I writing to action results, one of them is a HTTP GET and the another HTTP POST

    [HttpGet]
    public ActionResult DoTest()
    {
        Worksheet worksheets = new worksheets(..);
        return View(w);
    }

    [HttpPost]
    public ActionResult DoTest(Worksheet worksheet)
    {
        return PartialView("_Problems", worksheet);
    }

enter image description here

Now, Worksheet class has a property called Problems and this is a collection, but uses as an abstract class item.

public class Worksheet
{
    public List<Problem> Problems { get; set; }
}

Here's my abstract class and one implementation

public abstract class Problem
{
    public Problem() { }

    public int Id { get; set; }
    public abstract bool IsComplete { get; }

    protected abstract bool CheckResponse();
}

public class Problem1 : Problem
{
    ...
    public decimal CorrectResult { get; set; }

    // this is the only property of my implementation class which I need
    public decimal? Result { get; set;}

    public override bool IsComplete
    {
        get { return Result.HasValue; }
    }

    protected override bool CheckResponse()
    {
        return this.CorrectResult.Equals(this.Result.Value);
    }
}

I have right now, many implementations of Problem class, but I really need to get just one value of my implementation class. But it thrown the above image error.

What can I do to allow model binder recover that part of my abstracts classes

tereško
  • 58,060
  • 25
  • 98
  • 150
Darf Zon
  • 6,268
  • 20
  • 90
  • 149

1 Answers1

2

The following code would not compile:

var problem = new Problem();

... because the Problem class is abstract. The MVC engine cannot just create a Problem directly. Unless you give it some way to know which type of Problem to instantiate, there's nothing it can do.

It is possible to create your own ModelBinder implementation, and tell MVC to use it. Your implementation could be tied to a Dependency Injection framework, for example, so that it knows to create a Problem1 whenever a Problem class is requested.

Or you could simply change your action method to take a concrete type:

public ActionResult DoTest(IEnumerable<Problem1> problems)
{
    return PartialView("_Problems", 
                       new Worksheet {
                          Problems = problems.Cast<Problem>().ToList()
                       });
}
StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
  • can you tell me more about the DIF? I really have many implementations of the abstract class and I need a way that Model Binder recognizes the object – Darf Zon Jan 10 '13 at 16:23
  • @DarfZon: A DI framework like Ninject would be more applicable if you have just one expected implementation class, and you're just using the abstract class to avoid coupling your code too tightly. Since you have multiple types, you're going to need to figure out a way to determine which specific type you need as you are binding to the model. Raphael's link (http://stackoverflow.com/questions/7222533/polymorphic-model-binding) provides a good place to start. – StriplingWarrior Jan 10 '13 at 16:53