我可以为 POST 和 PUT API 请求使用自定义 JsonSerializer 来处理接口参数吗?
Posted
技术标签:
【中文标题】我可以为 POST 和 PUT API 请求使用自定义 JsonSerializer 来处理接口参数吗?【英文标题】:Can I use a custom JsonSerializer for POST and PUT API request to handle interface parameter? 【发布时间】:2021-11-05 13:01:29 【问题描述】:我正在尝试将接口参数作为我创建的 POST 和 PUT API 的请求对象的一部分传递,但我不确定如何添加 JSON 反序列化器以便能够指定哪个具体类用于哪个服务.如何指定我想将 FooRequestData 用于一个,将 FooOtherRequestData 用于另一个?
[ApiController]
[Route("api/[controller]")]
public class FooController
// POST api/<APIController>
[HttpPost]
public FooResponse Post(FooRequest request)
return FooService.Post(request);
// PUT api/<APIController>
[HttpPut]
public FooResponse Put(FooRequest request)
return FooService.Put(request);
public class FooRequest : IRequest<Foo>
public IRequestData RequestData get; set;
public class FooRequestData : IRequestData
public string Boo get; set;
public class FooOtherRequestData : IRequestData
public string Hoo get; set;
【问题讨论】:
*** 上围绕类似需求提供了各种问题/答案。它们都归结为您必须在 JSON 中包含足够的数据才能确定您应该使用哪种类型。您可以使用TypeNameHandling.Objects
使类型信息作为属性包含在 JSON 中。如果存在Boo
属性,您可以创建一个转换为一种类型的转换器,如果存在Hoo
,则转换为另一种类型。您可以将 FooRequest
模型更改为具有两个可选/可为空的属性,一个用于每种可能的类型,并期望填充正确的属性。
【参考方案1】:
我认为this answer to another question 可能适合您:创建一个result filter 并将其添加到您要指定行为的控制器中。
最初我认为TextOutputFormatter 可以工作,但似乎没有办法检查请求输出格式的控制器或服务。
【讨论】:
【参考方案2】:我了解您要执行的操作,但是它不起作用。问题不在于 API,而在于接口如何序列化/反序列化并转换为它们的继承类。
例如,如果 IRequestData
最初是 FooRequestData
,但您现在决定将其转换为 FooOtherRequestData
,则会引发错误,因为您无法将 IRequestData
转换为 FooOtherRequestData
,如果不是以 FooOtherRequestData
开头。
相反,我会推荐以下两件事之一:
选项 1:继续使用接口
接口实际上并不像转换为父类那样删除属性。这些属性仍然存在,只是无法访问。但是当您将它作为 json 对象返回时,它仍然会显示所有属性。
虽然这是在类之间传递,但我相当肯定它也会扩展到 API 请求。
当您想将它们用作输入时,只需将接口作为要求传递即可。
选项 2:添加特定转化
在代码中工作时,您可以添加检查以查看是否可以显式转换:
if(request.RequestData.GetType().IsAssignableTo(typeof(FooRequestData)))
var reqData = (FooRequestData)request.RequestData;
...
if(request.RequestData.GetType().IsAssignableTo(typeof(FooOtherRequestData)))
var reqData = (FooOtherRequestData)request.RequestData;
...
【讨论】:
您为“特定转换”列出的选项假定request
已经被序列化为具有正确的类型。如果是这样的话,做if(request.RequestData is FooRequestData reqData) ...
会更简单。但整个问题首先是关于如何让 JSON 序列化为正确的具体类型,而不是如何将 C# 对象转换为正确的类型。以上是关于我可以为 POST 和 PUT API 请求使用自定义 JsonSerializer 来处理接口参数吗?的主要内容,如果未能解决你的问题,请参考以下文章
javaservlet处理四种常用api请求get,put,post,delete
使用 POSTMAN 或任何其他方式批量 POST/PUT API 请求
REST API:请求正文为 JSON 或纯 POST 数据?