.NET Core 3.1中IActionResult返回JSON含冗余字段的解决咨询
问题描述
我尝试从API返回JSON对象,理论上可行,但数据被包裹在包含formatters、contentTypes、declaredType、statusCode等冗余内容的对象中,实际仅需返回纯净的数据数组。
冗余返回示例
{ "value": [ { "id": 2, "text": "foo", "values": [ { "pointName": "bar", "value": 1 } ] } ], "formatters": [], "contentTypes": [], "declaredType": null, "statusCode": 200 }
期望返回示例
[ { "id": 2, "text": "foo", "values": [ { "pointName": "bar", "value": 1 } ] } ]
问题源于需要返回错误码(如Forbidden、BadRequest),因此将返回类型从IEnumerable<ListObject>改为IActionResult,相关代码如下:
public class ListObject { public int ID { get; set; } public string Text { get; set; } public List<ObjectValue> values { get; set; } } public class ObjectValue { public string pointName { get; set; } public double value { get; set; } } [HttpPost] [Route("getPointDataList/{deviceName}")] [ProducesResponseType(typeof(IEnumerable<ListObject>),StatusCodes.Status200OK)] public IActionResult getPointDataList(string deviceName, [FromBody] string[] points) { try { if (points == null || points.Length == 0) return BadRequest("No points defined on request"); return getPointDataListInternal(deviceName, points); //该方法返回IActionResult,内部返回Ok(ListObject) } catch (Exception ex) { return BadRequest(ex.Message); } }
请问在.NET Core 3.1中,是否有简洁合理的方法去除返回对象中的冗余内容?
解决方案
出现冗余包装的核心原因是getPointDataListInternal返回的IActionResult被双重包装了——它内部已经通过Ok(ListObject)完成了结果包装,外层直接返回这个对象就会导致框架再次序列化整个IActionResult实例,从而带出冗余字段。
你可以通过两种简洁方式解决:
- 调整内部方法返回类型:将
getPointDataListInternal的返回类型改为IEnumerable<ListObject>,直接返回数据集合,再在外部方法中用Ok()包装:
// 修改内部方法返回类型 private IEnumerable<ListObject> getPointDataListInternal(string deviceName, string[] points) { // 原有业务逻辑,直接返回数据集合即可 } // 外部方法调用调整 return Ok(getPointDataListInternal(deviceName, points));
- 提取内部结果值重新包装:如果无法修改内部方法,可通过类型转换提取
OkObjectResult中的Value属性,再用Ok()重新包装:
var internalResult = getPointDataListInternal(deviceName, points) as OkObjectResult; if (internalResult?.Value is IEnumerable<ListObject> data) { return Ok(data); } return BadRequest("Failed to retrieve data");
另外,确认项目中没有自定义的结果格式化器干扰默认行为,ASP.NET Core 3.1的默认JSON格式化器在返回Ok(T)时,只会序列化T本身,不会添加冗余字段。
内容的提问来源于stack exchange,提问作者Ilkka
相关产品推荐
相关产品推荐

