Web API模型验证和默认值

本文关键字:默认值 验证 模型 API Web | 更新日期: 2023-09-27 17:50:51

这是我之前的问题Web API属性路由和验证的精神继承-可能吗?,我认为这个问题太笼统了,无法回答。这些问题大部分都解决了,但默认值的问题仍然存在。

基本上我已经解决了这个谜题的许多部分。我有这个:
[HttpGet]
[Route("test/{id}"]
public IHttpActionResult RunTest([FromUri]TestRequest request)
{
    if (!ModelState.IsValid) return BadRequest(ModelState);
    return Ok();
}

My TestRequest class:

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。但这里不是这样的)

Web API模型验证和默认值

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

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

更新:
在c# 6中,您不再需要在构造函数中初始化它。您可以直接将默认值赋给该属性:

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

正如DefaultValueAttribute的文档所述:

注意

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

在你没有为你的something属性提供值的情况下,该属性被初始化,ModelBinder没有值可以分配给它,因此该属性默认为其默认值

在构造函数中指定默认值适用于没有指定任何参数的情况,但当指定空白字符串时,null将被放入该字段。

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

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

请给我一个比这个更好的答案。