【问题标题】:Inheritance based custom model binding基于继承的自定义模型绑定
【发布时间】:2012-11-07 20:01:40
【问题描述】:

我需要创建一个发布操作来监听 ASP.NET MVC 4 中的一堆事件消息。有很多事件,所以我无法为每个事件创建一个操作。因此,最好使用其基类创建一个动作作为发布模型,使用自定义模型绑定器来填充事件。

一些事件如下所示:

public class QueryID : Identity<Guid>
{
    public QueryID(Guid id)
    {
        Identifier = id;
    }
}

public class QueryEvent : IEvent<QueryID>
{
    public QueryEvent(QueryID id)
    {
        Identity = id;
    }

    #region Implementation of IEvent<out QueryID>

    public QueryID Identity { get; private set; }

    #endregion
}

public class QueryCreated : QueryEvent
{
    public string ConnectionID { get; private set; }

    public QueryCreated(QueryID id, string connectionID)
        : base(id)
    {
        ConnectionID = connectionID;
    }
}

public class ColumnAdded : QueryEvent
{
    public string Column { get; private set; }

    public ColumnAdded(QueryID id, string column)
        : base(id)
    {
        Column = column;
    }
}

接收这些消息的操作方法如下所示:

[HttpPost]
    public ActionResult Index(IEvent<IIdentity> e)
    {
        // whatever

        return new EmptyResult();
    }

Identity 基类实现IEvent&lt;IIdentity&gt; 接口。

要完成此任务,模型绑定器会是什么样子?

谢谢

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-4


    【解决方案1】:

    单纯的模型绑定对您没有帮助。模型绑定的工作方式是,框架查看操作所期望的参数类型,使用反射创建该类型的默认实例,并使用表单中发送的数据来混合其上的每个公共属性。

    您的操作中的参数是一个接口,因此框架将无法创建实例。它只是不知道要创建接口的哪个实现。

    在一个例子中,我在要发布的表单中使用了一个隐藏字段来指示接口的哪个实现将绑定到 action 参数。但我有一个简单的场景。一个接口,两个实现。每一个对应一个表格。所以我可以有一个隐藏的文件告诉我我希望我的模型绑定器创建的类的名称。

    在您的情况下,如果事件的发起者(我认为是某个客户端应用程序)知道应该调用哪个模型,那么您可以将该信息与其他信息一起发送到您的操作。

    很遗憾,我目前没有代码。如果您认为这个解决方案可能有帮助,我可以挖掘代码。

    【讨论】:

    • 嗨 Suhas,是的,你是对的,这是一个相当复杂的场景。我考虑过您建议的类似解决方法,但我不希望客户端“知道”服务器端的任何实现细节。他们只需以 JSON 格式发送已知命令,这个自定义模型绑定器就会发挥它的魔力。
    • 如果客户知道要发送哪个命令(虽然是 json 格式),他们基本上就拥有了您需要的信息。我觉得没有别的办法了
    • 当客户端发送该操作的命令的 JSON 序列化版本时,此自定义模型绑定器应该能够将该 JSON 反序列化到命令对象。模型绑定器如何知道要启动哪种类型并将属性映射到它?例如,我们发送 CreateQuery 命令。 JSON 看起来像 { Idendity: { Identifier: "some id" }, ConnectionID: "some connection" }。此 JSON 中没有类型信息。假设我使用了动态对象,没关系,我仍然不知道类型。继续……
    • 可能我需要发送一个消息信封(我将其创建为 MessageEnvelope),我可以发送类型名称 (CreateQuery) 作为键。 Body 将是命令对象。然后我可以使用主体内的参数激活该对象的实例。我试试这个...
    • 我应该早点详细说明我的方法。我指的是消息信封之类的东西。我很确定这适用于您的情况。
    【解决方案2】:

    可以编写自定义模型绑定器提供程序以支持 MVC3+ 中的接口,请参阅这篇文章。

    http://www.matthidinger.com/archive/2011/08/16/An-inheritance-aware-ModelBinderProvider-in-MVC-3.aspx

    然后将继承特定接口的任何类型传递给相关的模型绑定器,然后可能会尝试 as ConcreteClass 和 null 检查以找出实际类型是什么。我没有尝试过,因为我有一个类似的问题,一直无法解决,但相关帖子看起来指向了正确的方向。

    【讨论】:

      猜你喜欢
      • 2013-05-20
      • 1970-01-01
      • 1970-01-01
      • 2013-03-09
      • 1970-01-01
      • 2016-12-20
      • 1970-01-01
      • 2021-09-17
      • 1970-01-01
      相关资源
      最近更新 更多