C# API中如何检测POST请求Payload是否包含指定布尔字段OptOut
嘿,我太懂你这个困扰了!布尔类型的默认值就是false,所以不管你的POST请求里到底有没有传OptOut这个字段,绑定到Mailing对象之后,这个属性都会是false——你根本没法区分是用户主动传了false,还是压根就没提这个字段的事儿,对吧?
给你几个实用的解决办法,按需选就行:
最省心的方案:把布尔类型改成可空布尔(
bool?)
直接修改你的Mailing类,把OptOut的类型从bool改成bool?(可空布尔)。可空类型的默认值是null,这样一来:- 如果请求Payload里没传
OptOut,这个属性就是null - 如果传了
true或者false,属性就会被赋值成对应的布尔值
代码改完是这样的:
public class Mailing { public bool? OptOut { get; set; } // ... 其他属性照原样保留 }之后判断的时候,只要检查
mailing.OptOut.HasValue:如果返回true,就说明请求里确实传了这个字段;返回false就是没传。- 如果请求Payload里没传
不想改模型?直接解析原始请求体
要是你不想动现有的Mailing模型,那可以直接读取原始的请求JSON内容,然后检查字段是否存在。比如用Newtonsoft.Json(也就是Json.NET)来解析:// 先读取原始请求流的内容 using var streamReader = new StreamReader(Request.Body); var requestJson = await streamReader.ReadToEndAsync(); var payloadObj = JObject.Parse(requestJson); // 检查是否包含OptOut字段 bool isOptOutPresent = payloadObj.ContainsKey("OptOut");注意哦,ASP.NET Core里读取
Request.Body之后,默认流的位置会到末尾,要是之后还要用模型绑定的话,记得先调用Request.EnableBuffering(),读完后把流的位置重置到开头。ASP.NET Core专属:用ModelState判断
如果你是在ASP.NET Core里开发API,还可以通过ModelState来判断绑定器有没有尝试处理过OptOut字段。模型绑定器只要在请求里找到对应的字段,不管绑定成功还是失败,都会在ModelState里添加这个字段的条目:[HttpPost] public IActionResult ProcessMailing([FromBody] Mailing mailing) { // 检查ModelState里是否有OptOut的键 bool hasOptOutInPayload = ModelState.ContainsKey("OptOut"); // 后续逻辑... return Ok(); }这个方法不用改模型,但要注意:如果请求里传了
OptOut但格式不对(比如传了个字符串"abc"),ModelState里也会有这个键,只是对应的状态是无效的,所以如果需要区分“传了但格式错”和“没传”,还要结合ModelState.IsValid来进一步判断。
备注:内容来源于stack exchange,提问作者Kung Fu Ninja

