ASP.NET MVC 2 - 绑定到抽象模型
如果我有以下强类型视图:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<XXX.DomainModel.Core.Locations.Location>" %>
其中 Location 是一个抽象类。
我有以下控制器,它通过 POST: 接受强类型模型:
[HttpPost]
public ActionResult Index(Location model)
我收到一个运行时错误,指出“无法创建抽象类,
这当然是有道理的。但是- 我不确定这里最好的解决方案是什么。
我有很多具体类型(大约 8 个),在这个视图中您只能编辑
我尝试过 的属性。 > 要做的是为所有不同的具体类型创建重载,并在通用方法中执行我的逻辑
[HttpPost]
public ActionResult Index(City model)
{
UpdateLocationModel(model);
return View(model);
}
[HttpPost]
public ActionResult Index(State model)
{
UpdateLocationModel(model);
return View(model);
}
等等
然后:
[NonAction]
private void UpdateLocationModel (Location model)
{
// ..snip - update model
}
但这也不起作用,MVC 抱怨操作方法不明确(。也有道理)
我们能做什么?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为这个抽象类编写一个自定义模型绑定器怎么样:
只有当您有一个根据某些用户操作动态插入输入元素的表单时,这才有意义。在这种情况下,您需要传递一些附加参数来指示您需要哪个具体类。否则我会坚持使用具体的视图模型作为操作参数。
How about writing a custom model binder for this abstract class:
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.
您还可以构建适用于所有抽象模型的通用 ModelBinder。我的解决方案要求您向视图添加一个名为“ModelTypeName”的隐藏字段,并将值设置为所需的具体类型的名称。
但是,应该可以使这个东西变得更智能,并通过将类型属性与视图中的字段匹配来选择具体类型。
在 Application_Start() 中的 Global.asax.cs 文件中:
CustomModelBinder:
You can also build a generic ModelBinder that works for all of your abstract models. My solution requires you to add a hidden field to your view called 'ModelTypeName' with the value set to the name of the concrete type that you want.
However, it should be possible to make this thing smarter and pick a concrete type by matching type properties to fields in the view.
In your Global.asax.cs file in Application_Start():
CustomModelBinder:
只是把它扔在那里 - 我对其他人可能会回答的内容非常感兴趣,但这就是我在遇到类似情况时最终所做的事情;
基本上,我没有使用模型类作为 Action 方法中的参数,而是传入
FormCollection
并测试几个已知的鉴别器以找出要创建/编辑的类型,然后使用TryUpdateModel
从那里开始。似乎可能有更好的方法,但我从来没有时间更多地思考它。
Just to throw it out there - I'm very much interested in what others might answer, but this is what I ended up doing in the case where I had a similar situation;
Basically, I did not use the model class as a parameter in the Action method, instead passing in
FormCollection
and testing a couple known discriminators to figure out which type to create/edit, then usedTryUpdateModel
from there.It seemed there might be a better way, but I'd never gotten around to thinking about it more.