如何重载基于 HttpPost Web API 方法的 Json 数据类型属性

发布于 2025-01-10 17:27:39 字数 271 浏览 0 评论 0原文

我被要求实现一个特定路由的 REST Web API,其中可以发布两种不同的 Json 数据类型中的任何一种。

这会导致抛出以下异常:

Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints.

是否有一个属性可以放置在 Web 方法上,引用 Json 有效负载的属性,以便消除两种可能的数据类型的歧义?

I am asked to implement a REST Web API to a specific route, where either of two different Json Datatypes may be posted.

This results in the following exception being thrown:

Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints.

Is there an Attribute that can be placed on the Web Methods, referencing Properties of the Json payloads so as to disambiguate the two possible Datatypes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

迷路的信 2025-01-17 17:27:39

这是此处已介绍,但我会补充一点。

这样做并不是好的 API 设计,并且违背了 Swagger / OpenAPI 规范来执行您所要求的操作。

使用相同的 HTTP 方法(在您的例子中为 POST)执行此操作的唯一方法是在两个模型中执行一个操作。检查哪一个不为空,然后路由到正确的方法来处理该逻辑。

如果您可以使用不同的 HTTP 动词,那么您在技术上可以做到这一点,并拥有两个单独的操作方法(如 POST 和 PUT),但您不会“正确”使用它们,并且根据您的问题和需求,我怀疑无论如何你都可以这样做。

This was covered here but I'll add a little bit.

It's not good API design to do that and goes against Swagger / OpenAPI specifications to do what you're asking.

The only way to do this with the same HTTP method (POST in your case) is to have one action that takes in both models. Check which one isn't null to then route to the correct method to handle that logic.

If you can get away with using a different HTTP verb you could technically do that and have two separate action methods (like POST and PUT), but you wouldn't be using them "correctly" and based on your question and need, I doubt you can do that anyway.

儭儭莪哋寶赑 2025-01-17 17:27:39

您可以将请求正文作为字符串读取,然后尝试决定要反序列化的类型:

[HttpPost]
[Route("api/mypath")]
public async Task<IActionResult> MyMethod()
{
  request.Body.Position = 0;

  var reader = new StreamReader(request.Body, Encoding.UTF8);

  var body = await reader.ReadToEndAsync();

  if(body.Contains("A))
  {
     var A = JsonConvert.DeserializeObject<A>(body);
  }
  else{
     var B = JsonConvert.DeserializeObject<B>(body);
  }
}

并添加中间件以启用请求缓冲:

app.Use(next => context => {
    context.Request.EnableBuffering();
    return next(context);
});

您可以阅读有关它的更多信息 此处

You can read the request body as a string and then try to decide which type to deserialize in:

[HttpPost]
[Route("api/mypath")]
public async Task<IActionResult> MyMethod()
{
  request.Body.Position = 0;

  var reader = new StreamReader(request.Body, Encoding.UTF8);

  var body = await reader.ReadToEndAsync();

  if(body.Contains("A))
  {
     var A = JsonConvert.DeserializeObject<A>(body);
  }
  else{
     var B = JsonConvert.DeserializeObject<B>(body);
  }
}

And add a middleware to enable request buffering:

app.Use(next => context => {
    context.Request.EnableBuffering();
    return next(context);
});

You can read more about it here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文