这是我之前提出的Web API attribute routing and validation - possible?问题的精神继承者,我认为这个问题过于笼统。大多数问题都已解决,但默认值问题仍然存在。
基本上我已经解决了许多难题。我有这个:
[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
的查询字符串中没有参数,则模型为“有效”,而something
为null
。
如果我为something
指定空白值(即GET test/123?something=
),则默认值开始播放,模型再次有效。
这是为什么?如何在此模型中获取默认值?作为奖励,为什么在未指定参数时,不使用默认值,但是当空白字符串明确特定时,使用默认值?
(我一直在浏览ASP.NET堆栈源代码,并且在模型绑定器和绑定上下文中非常深入。但我最好的猜测是不对的 - 看起来好像使用了DefaultValueAttribute
仅当参数值为null
时才会出现这种情况。
答案 0 :(得分:4)
您需要在模型的构造函数中初始化默认值:
public class TestRequest
{
public TestRequest()
{
this.something = "SomethingDefault";
}
public string id { get; set; }
[DefaultValue("SomethingDefault")]
public string something { get; set; }
}
正如documentation of the DefaultValueAttribute所述:
注意
DefaultValueAttribute不会导致成员 使用属性值自动初始化。你必须设置 代码中的初始值。
如果您没有为something
属性提供任何值,则会初始化该属性,并且ModelBinder
没有分配给它的值,因此property默认为默认值。
答案 1 :(得分:3)
指定构造函数中的默认值适用于根本没有指定参数的情况,但是当指定空字符串时,null
会被放入字段中。
因此,添加[DefaultValue("")]
实际上效果最好 - 当指定空字符串时,传入空字符串。然后构造函数可以指定缺少参数的默认值。
为了解决这个问题,我创建了PreserveBlankStringAttribute
,派生自DefaultValueAttribute
,相当于[DefaultValue("")]
。
我非常欢迎比这更好的答案。