Web API模型验证和默认值

时间:2015-05-27 12:26:37

标签: c# asp.net-web-api

这是我之前提出的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的查询字符串中没有参数,则模型为“有效”,而somethingnull

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

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

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

2 个答案:

答案 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("")]

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