You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Asp.Net Core 5 POST请求无法同时获取路由与Body参数如何解决?

问题原因

第一次报错的根源

你给Model的string类型Token属性加了[FromBody]时,ASP.NET Core会尝试将整个请求正文直接反序列化为string类型,但你传递的是JSON对象{"token":"ABC"},不是纯字符串文本,所以反序列化失败,抛出类型转换错误。如果此时请求体直接传纯字符串"ABC"(不加外层JSON结构),其实可以正常拿到Token和路由的UserId,但这种传参方式不符合常规JSON接口的使用习惯。

第二次UserId为null的根源

你给整个Model参数加了[FromBody]后,ASP.NET Core会完全从请求正文反序列化整个Model对象,会直接忽略路由、查询字符串等其他来源的值,你的JSON参数里没有传userId,所以UserId自然为null。


解决方案

方案1:拆分Action参数(最推荐)

直接将不同来源的参数拆分声明,符合ASP.NET Core默认绑定规则,逻辑清晰:

// 定义Body参数对应的DTO
public class ConfirmEmailRequest
{
    public string Token { get; set; }
}

[HttpPost("users/{userId:int}/confirm-email")]
public async Task<IActionResult> ConfirmEmail([FromRoute] int userId, [FromBody] ConfirmEmailRequest request)
{
    // userId 从路由取值,request.Token 从请求Body取值
}

请求体还是保持你原来的{"token":"ABC"}即可,无需修改前端请求逻辑。

方案2:保留单个Model参数,调整属性结构

如果你一定要把所有参数都封装在同一个Model类里,可以将Body对应的属性修改为嵌套类,适配你传递的JSON结构:

public class ConfirmEmailModel
{
    [FromRoute] public int? UserId { get; set; }
    [FromBody] public ConfirmEmailRequest Payload { get; set; }

    public class ConfirmEmailRequest
    {
        public string Token { get; set; }
    }
}

// Action参数不要加[FromBody]
[HttpPost("users/{userId:int}/confirm-email")]
public async Task<IActionResult> ConfirmEmail(ConfirmEmailModel model)
{
    // model.UserId 来自路由,model.Payload.Token 来自请求Body
}

内容的提问来源于stack exchange,提问作者Miguel Moura

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 02:45:00