【发布时间】:2015-05-27 12:26:37
【问题描述】:
这是我之前的问题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。但这里不是这样)
【问题讨论】:
-
不是批评的意思,但是您是否在传递给外部各方之前自己使用此服务? (即吃你自己的狗粮?)。我一直觉得使用 ModelState 验证和 BadRequest 的简单返回对您的 API 用户(开发人员是这里的用户)完全没用,因为它完全不清楚出了什么问题。拥有一个规则引擎并在 badRequest 的主体中传回有用的错误消息要好得多,模型状态远没有帮助。这同样适用于在您的其他问题中进行验证的属性生根。
-
Macb - 是的,这是一个内部原型。我喜欢在这里利用 ModelState 的想法有几个原因:1)模型仅在“Web 层”中,因此可以具有特定于层的注释,2)请求上的注释是定义合同的好方法,3 ) 我们正在考虑为 Angular 编写客户端组件,它可以使用基于此的消息突出显示适当的字段,并且 4) 我也热衷于探索基于注释自动生成 API 文档。许多 if 语句在代码中隐藏了所有这些。属性路由对于“实际上是 RESTful”的 API 来说也很棒 :)
-
对不起,我可能误解了 - 你说一个简单的回报是无用的和不清楚的。但是
return BadRequest(ModelState)为调用者提供了一个很好的 JSON 细分,说明了请求失败的原因以及导致它失败的原因——除非我误解了? -
我的语言有点强 :-) 这真的取决于您的 API 用户,从您的描述来看,听起来您正在构建内部使用/在您自己的外部网站上使用 - 其中案例模型验证很棒。就我个人而言,我喜欢对返回给用户的内容进行一点控制,即“为什么”这种失败的消息而不是通过模型验证获得的“这个”失败消息。例如,假设一个“电话”号码字段,很高兴被告知该号码与英国固定电话格式不匹配 - 而不是它无法匹配给定的正则表达式。
-
添加到上面,我喜欢我的模型是可移植的。例如,我所有的模型都在一个可移植类库中,以允许在消费者(xamarin iOS/Android,Windows 商店应用程序)上重用模型,此外,我们将 dto 对象转换为带有type.litesolutions.net 的类型脚本,用于我们的淘汰赛web 应用程序,最大限度地重用 c# 模型。
标签: c# asp.net-web-api