6

我正在尝试执行 a 的自定义实现MediaTypeFormatter,但bool CanReadType(Type type)始终使用类型IKeyValueModel而不是我的类型调用该方法MyProduct

在我的 API 控制器中,我有:

[HttpPost]
public Task Save(MyProduct product)

我看过一些例子(例子1例子2),我也试过代码:

protected override bool CanReadType(Type type)
{
    if (type == typeof(IKeyValueModel))
        return false;
      return true;
}

但后来我得到一个“MissingMethodException:没有为此对象定义无参数构造函数”,因为我的模型类型没有无参数构造函数。所以看起来因为CanReadType返回 false IKeyValueModel,框架使用了另一个媒体类型格式化程序。实际上,该方法OnReadFromStreamAsync永远不会被击中。

我希望能够控制我的模型如何反序列化,我想获得真正的类型而不是IKeyValueModel.

这已经在带有模型绑定器的 MVC 中运行良好。

干杯。

2012 年 5 月 29 日更新:

如果我删除默认的 json 格式化程序,它可以工作:

    public static void RegisterApis(HttpConfiguration config)
    {
        config.Formatters.Clear();

但是我想保留两者,我怎么能指出我想使用哪一个?

问候。

4

1 回答 1

3

如果您需要控制序列化,最好使用 Json.NET 的灵活性特性(参见此处此处此处)来控制而不是为此编写媒体类型格式化程序。

Json.NET现在是 ASP.NET Web API 中的默认格式化程序。


更新

我的对象没有无参数构造函数,并且属性是只读的。我也有继承自 DynamicObject 的对象,所以假设我的业务实体并非微不足道。

我可能会告诉你如何在脚上开枪。但我宁愿解释如何避免出现这些问题,因为我相信你遇到了这些问题,因为你的方法中有反模式。

首先,您要寻找的不是另一种媒体类型格式化程序。你需要一个不同的序列化器或者只需要配置你的序列化器。

但更重要的是,将您的业务实体直接序列化给客户端并不是一个好主意。我们需要在这里称为视图模型的 DTO。这样的类只是状态持有者,没有逻辑,没有魔法。序列化它们应该没有问题。

您可以使用 AutoMapper 等将您的实体映射到视图模型,而无需更多的开发成本。始终建议从表示层抽象出您的域模型。

于 2012-05-29T10:39:17.393 回答