28

我在问是否有人知道是否可以将继承自抽象类的具体类传递给 Web Api。

例如:

public abstract class A
{
    A();
}

public class B : A
{
}

[POST("api/Request/{a}")]
public class Request(A a)
{
}

目前我环顾四周,大多数解决方案似乎都说使用 TypeNameHandling 会起作用。

JsonMediaTypeFormatter jsonFormatter = new JsonMediaTypeFormatter();
jsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto;

然而,情况并非如此。此外,我的模型正在从控制台应用程序传递到 webapi。我读过我可能能够反序列化 json 对象,在尝试了几次之后,我决定这不起作用。

我已经研究过创建一个客户模型绑定器,但是,我不想让我的应用程序变得更加复杂。目前我从具有 3 个模型的抽象类继承,但将来可能会扩展它。正如您可能注意到的,添加自定义模型绑定器可能需要多个绑定器,除非有一种方法可以使一个绑定器对所有类型的抽象类都通用。

为了在我的控制台应用程序中对此进行扩展,我已经实例化了 b 类,然后在发布到我的 webapi 之前将其传递给 ObjectContent

item = B();

//serialize and post to web api
MediaTypeFormatter formatter;
JsonMediaTypeFormatter jsonFormatter = new JsonMediaTypeFormatter();
jsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto;
formatter = jsonFormatter;

_content = new ObjectContent<A>(item, formatter);
var response = _client.PostAsync("api/Request", _content).Result;

当调用 webapi 操作时,对象为空

4

4 回答 4

2

如果一个人真的想实现问题中提出的问题,那么有一种自定义方法可以做到这一点。

首先,创建一个继承自的自定义 json 转换器JsonConverter,在其中选择一个目标类并反序列化一个实例。

然后,在您的设备中WebApiConfig.Register添加您的新转换器config.Formatters.JsonFormatter.SerializerSettings.Converters并享受这个怪物的运行。

你应该这样做吗?不。

了解如何使用此类 API 不会给任何新用户带来任何乐趣,记录这一点并不容易,最重要的是 - 以这种方式实现它没有任何好处。如果输入类型不同,那么它们应该使用具有不同 URL 的单独 API 方法。如果只有少数属性不同 - 将它们设为可选。

为什么这个例子不起作用?TypeNameHandling来自 Json.NET,Web API对此一无所知,并且类型信息不是 JSON 规范的一部分,因此没有解决此特定问题的标准方法。

于 2020-04-13T07:53:50.760 回答
0

您可以为此目的使用JsonSubTypes转换器。它是使用 Json.NET 进行多态反序列化的非常有用且简单的工具。

于 2021-11-24T22:25:54.503 回答
0

请更改[POST("api/Request/{a}")][POST("api/Request")]. 您的参数来自身体,而不是来自路线。

于 2021-01-28T09:35:34.293 回答
-1

这可以通过默认模型绑定来实现。检查以下方法。

public abstract class RequestBase
{
    public int ID { get; set; }
}

public class MyRequest : RequestBase
{
    public string Name { get; set; }
}



[RoutePrefix("api/home")]
public class HomeController : ApiController
{
    [HttpPost]
    [Route("GetName")]
    public IHttpActionResult GetName([FromBody]MyRequest _request)
    {
        return Ok("Test");
    }
}

在此处输入图像描述

于 2019-08-22T11:01:36.247 回答