Web API模型validation和默认值

这是我之前的问题Web API属性路由和validation的精神inheritance者- 可能吗? 我认为这个问题太过笼统。 大多数问题都已解决,但默认值问题仍然存在。

基本上我已经解决了许多难题。 我有这个:

[HttpGet] [Route("test/{id}"] public IHttpActionResult RunTest([FromUri]TestRequest request) { if (!ModelState.IsValid) return BadRequest(ModelState); return Ok(); } 

我的TestRequest类:

 public class TestRequest { public string id { get; set; } [DefaultValue("SomethingDefault")] public string something { get; set; } } 

问题是,如果something查询字符串中没有参数,则该模型为“有效”,但somethingnull

如果我为something指定了空白值(即GET test/123?something= ),则默认值开始起作用,模型再次有效。

为什么是这样? 如何在此模型中获取默认值? 作为奖励,为什么在未指定参数时,不使用默认值,但是当空白字符串明确特定时,使用默认值?

(我一直在浏览ASP.NET堆栈源代码,并且在模型绑定器和绑定上下文中非常深入。但我最好的猜测是不对的 – 看起来只有在参数值为null时才使用DefaultValueAttribute但这不是这里的情况)

您需要在Model的构造函数中初始化默认值:

 public class TestRequest { public TestRequest() { this.something = "SomethingDefault"; } public string id { get; set; } [DefaultValue("SomethingDefault")] public string something { get; set; } } 

作为DefaultValueAttribute的文档说明:

注意

DefaultValueAttribute不会导致使用属性的值自动初始化成员。 您必须在代码中设置初始值。

如果您没有为您的something属性提供任何值,则会初始化该属性,并且ModelBinder没有要分配给它的值,因此该属性默认为其默认值。

指定构造函数中的默认值适用于根本没有指定参数的情况,但是当指定空字符串时,会将null放入字段中。

因此,添加[DefaultValue("")]实际上效果最好 – 当指定空白字符串时,传入空字符串。然后构造函数可以指定缺少参数的默认值。

为了解决这个问题,我创建了PreserveBlankStringAttribute ,派生自DefaultValueAttribute ,它相当于[DefaultValue("")]

我非常欢迎比这更好的答案。