Web API模型验证和默认值

Kie*_*one 5 c# asp.net-web-api

这是我先前提出的Web API属性路由和验证问题的精神继任者-可能吗?,我认为这太笼统了。这些问题大部分已解决,但默认值问题仍然存在。

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

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

我的TestRequest课:

public class TestRequest
{
    public string id { get; set; }

    [DefaultValue("SomethingDefault")]
    public string something { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

如果我为somethingGET test/123?something=)指定一个空白值,则默认值起作用,并且该模型再次有效。

为什么是这样?如何在此处将默认值输入模型?另外,为什么在未指定参数的情况下不使用默认值,而在明确指定空白字符串的情况下使用默认值呢?

(我一直在浏览ASP.NET堆栈源代码,并深陷于模型绑定器和绑定上下文中。但是我的最佳猜测不可能是正确的-看起来DefaultValueAttribute仅当参数值为时才使用null。这里不是这种情况)

Kon*_*nev 5

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

public class TestRequest
{
    public TestRequest()
    {
        this.something = "SomethingDefault";
    }

    public string id { get; set; }

    [DefaultValue("SomethingDefault")]
    public string something { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

更新:
使用C#6,您不再需要在构造函数中对其进行初始化。您可以将默认值直接分配给属性:

public class TestRequest
{
    public string id { get; set; }

    [DefaultValue("SomethingDefault")]
    public string something { get; set; } = "SomethingDefault";
}
Run Code Online (Sandbox Code Playgroud)

作为DefaultValueAttribute的文档说明:

注意

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

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