ASP.NET MVC 2 - 如何使用界面作为强类型视图的类型

ASP.NET MVC 2 - 如何使用界面作为强类型视图的类型

问题描述:

我想让我的具体类与我的观点分开。没有使用强类型视图,我很好。我只是在控制器方法签名中使用一个大参数列表,然后使用我的服务层工厂方法创建我的具体对象。ASP.NET MVC 2 - 如何使用界面作为强类型视图的类型

这实际上对我来说很好,但是让我思考并且在一点玩法之后,我意识到控制器方法接受接口作为方法参数是不可能的 - 因为它没有办法实例化它。无法通过IDE使用接口创建强类型视图(实际上这很有意义)。

所以我的问题。有没有办法告诉控制器如何使用我的服务层工厂方法实例化接口参数?

我想从转换:

[Authorize] 
[AcceptVerbs(HttpVerbs.Post)] 
[UrlRoute(Path = "Application/Edit/{id}")] 
public ActionResult Edit(String id, String TypeCode, String TimeCode, String[] SelectedSchoolSystems, 
      String PositionChoice1, String PositionChoice2, String PositionChoice3, String Reason, String LocationPreference, 
      String AvailableDate, String RecipientsNotSelected, String RecipientsSelected) { 

    //New blank app 
    IApplication _application = ApplicationService.GetById(id); 

喜欢的东西

[Authorize] 
[AcceptVerbs(HttpVerbs.Post)] 
[UrlRoute(Path = "Application/Edit/{id}")] 
public ActionResult Edit(String id, IApplication app) { 

      //Don't need to do this anymore 
      //IApplication _application = ApplicationService.GetById(id); 
+0

感谢您的优秀投入。巨大的帮助。 – Rake36 2010-03-26 00:01:10

+0

这已经很多个月了,但是经过很多编码 - 我意识到即使自定义模型绑定可能是正确的答案,但使用强类型视图模型对我来说是最好的。关键是View Model与我的数据库对象相比经常不同。 – Rake36 2010-07-13 20:27:38

您需要的视图模型层。

使用接口抽象出业务层实体可能是有意义的,但抽象Web应用程序特定实体(大多数情况下我猜)没有多大意义。这将允许您针对实现进行编码。

尝试从窗体绑定实体而不访问数据库也会带来很多麻烦。

+0

也许我混淆了架构不当,但我已经有一个数据访问层和一个服务层 - 所以我把MVC网站作为表示层,我不想创建只是副本的视图模型我的数据图层类。我误以为接口应该足够好吗? – Rake36 2010-03-25 12:45:39

+0

@ Rake36在某些情况下可能就足够了。它总是依赖于上下文。我只是说,添加适当的视图模型可以轻松解决这个特定的问题(但会增加视图模型和映射逻辑的代码库)。 – 2010-03-25 13:31:49

+0

@ Rake36你可能会发现这篇文章很有用 - http://bit.ly/9Bxpfj我猜 - '外部耦合'是什么让你的情况麻烦。 – 2010-03-25 13:45:54

自定义模型绑定。只需让模型绑定器构建派生类的实例并将其作为接口返回。

另一方面,为什么?通常,您将视图和控制器参数都使用特定于视图的模型。每个视图/动作都有特定的模型需求。我可以理解你为什么想从一个通用的接口或抽象类中派生它们 - 例如,你的母版页有一套可以使用的通用信息,但为什么特定的动作需要接收数据作为抽象?难道它不知道它需要的数据类型,只是使用正确的派生类作为参数类型?

+0

控制器不知道要使用哪个派生类。只有服务层。我曾想过也许我可以继续创建视图特定的模型,然后将这些模型用作服务层方法的参数。我试图避免在视图模型和具体类之间进行任何映射。那有意义吗? – Rake36 2010-03-25 12:53:58

+0

我明白你在说什么,但我认为你走错了路。我发现当你有视图模型和数据模型时,事情会变得更好。总而言之,我发现我需要用视图的其他数据来扩充我的数据模型,并将其封装在视图特定的模型中似乎是最好的方法。 – tvanfosson 2010-03-25 13:26:24

+0

谢谢。我将尝试这个想法以及自定义模型绑定方法。我会在这里回复我的结果。 – Rake36 2010-03-25 23:45:27

你可以写一个自定义模型粘结剂,将实例化一个正确类型:

public class MyModelBinder: DefaultModelBinder 
{ 
    protected override object CreateModel(
     ControllerContext controllerContext, 
     ModelBindingContext bindingContext, 
     Type modelType 
    ) 
    { 
     return // ... instantiate your model here 
    } 
} 

然后:

public ActionResult Edit(
    string id, 
    [ModelBinder(typeof(MyModelBinder))] IApplication app 
) 
{ 
    ... 
} 
+0

到目前为止,我还没有看过定制模型粘合剂。感谢这个例子。 – Rake36 2010-03-25 12:47:36