Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
222 views
in Technique[技术] by (71.8m points)

c# - ASP.NET MVC 2 - Binding To Abstract Model

If i have the following strongly-typed view:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<XXX.DomainModel.Core.Locations.Location>" %>

Where Location is an abstract class.

And i have the following Controller, which accepts a strongly-typed Model via a POST:

[HttpPost]
public ActionResult Index(Location model)

I get a runtime error stating "Cannot Create Abstract Class

Which of course makes sense. However - i'm not sure what the best solution is here.

I have many concrete types (around 8), and this is a view where you can only edit properties of the abstract class.

What i've tried to do is create overloads for all the different concrete types, and perform my logic in a common method.

[HttpPost]
public ActionResult Index(City model)
{
   UpdateLocationModel(model);
   return View(model);
}

[HttpPost]
public ActionResult Index(State model)
{
   UpdateLocationModel(model);
   return View(model);
}

etc etc

And then:

[NonAction]
private void UpdateLocationModel (Location model)
{
   // ..snip - update model
}

But this doesn't work either, MVC complains the action methods are ambiguous (also makes sense).

What do we do? Can we simply not bind to an abstract model?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

How about writing a custom model binder for this abstract class:

public class CustomBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        // TODO: based on some request parameter choose the proper child type
        // to instantiate here
        return new Child();
    }
}

This make sense only if you have a form where input elements are inserted dynamically based on some user action. In this case you need to pass some additional parameter to indicate which concrete class you need. Otherwise I would stick to concrete view models as action parameters.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...