c# - 您是否应该为参数创建一个 DTO,为正文创建一个 DTO,为查询创建一个,...?
问题描述
所以让我们假设你有一个 API 端点
- 1 到n 个参数
- 1 到n 个身体值
- 1 到n 个查询
您想创建一个 DTO 来获取和验证所有这些值。您可能知道整个请求不可能有一个 DTO 类,所以这不起作用:
public class Dto
{
[FromRoute]
public int Id { get; set; }
[FromBody]
public int Foo { get; set; }
}
解析器只会设置Foo
字段并忽略该Id
字段。调用https://localhost:5001/foo/1时,该Id
字段的默认值为 0,而不是 1。可以为 url 参数创建一个 DTO,为正文创建一个 DTO,为查询创建一个 DTO,如下所示
public class ParamsDto
{
public int FirstId { get; set; }
public int SecondId { get; set; }
}
// ... same for the body and queries ...
然后你可以像这样标记那些 dto [FromRoute] ParamsDto paramsDto, [FromBody] BodyDto bodyDto, [FromQuery] QueryDto queryDto
。您可能有一个多层架构,并且您的 Web API 项目与一个需要 DTO 的层通信,该 DTO 是上面显示的所有 3 个 DTO 的组合。因此,您必须将这 3 个对象合并为一个大 DTO,例如使用AutoMapper将请求 DTO 转换为命令对象(来自Mediatr)。
在文件夹结构、命名约定等方面是否有处理多个 DTO 的最佳实践?因为您可能必须为 params 创建一个 DTO,为 body创建一个 DTO,而不是调用 DTOUpdateProductAmountFromOrderByIds
来获取orderId
,productId
和(of products) 。我知道这不是最好的例子,因为这里并不真正需要 DTO,但我们假设您将对 ID 进行复杂的验证,并且正文包含多个值。你不想在你的控制器文件中有那么多的验证注解。在将这些单独的 DTO 合并为一个大的方面,这种方法对我来说看起来真的很混乱,所以也许有更好的方法。amount
UpdateProductAmountFromOrderByIdsParamsDto
UpdateProductAmountFromOrderByIdsBodyDto
解决方案
这是 asp.net core 3.0 的工作演示:
模型:
public class Dto
{
[FromRoute(Name = "")]
public Test Test { get; set; }
[FromBody]
public Sample Sample { get; set; }
public ApiVersion ApiVersion { get; set; }
}
public class Test
{
public string Col1 { get; set; }
public int Col2 { get; set; }
public bool Col3 { get; set; }
}
public class ApiVersion
{
public int VersionId { get; set; }
public string VersionName { get; set; }
}
public class Sample
{
public int Foo { get; set; }
public string Name { get; set; }
}
控制器:
[ApiController]
[Route("api/[controller]")]
public class ValuesController : Controller
{
// GET: api/<controller>
[HttpGet("col1/{col1}/col2/{col2}/col3/{col3}")]
public async Task<IActionResult> Get([FromQuery]Dto dto)
{
return Ok(dto);
}
}
请求网址:https://localhost:44393/api/values/col1/1/col2/2/col3/true?apiversion.versionId=1&apiversion.versionName=aaa
更新:
public class Dto
{
//[FromRoute(Name = "")]
//public Test Test { get; set; }
[FromRoute]
public string Col1 { get; set; }
[FromRoute]
public int Col2 { get; set; }
[FromRoute]
public bool Col3 { get; set; }
[FromBody]
public Sample Sample { get; set; }
public ApiVersion ApiVersion { get; set; }
}
推荐阅读
- javascript - Javascript:按单列重复数据删除二维数组
- prettier - 停止格式化最小文件?
- angular - Angular/Express GET 调用有时有效,有时失败。出现错误 [ERR_HTTP_HEADERS_SENT]:在将标头发送到客户端后无法设置标头
- reactjs - 将传递函数作为没有 jsx 的道具反应
- javascript - 为什么 Javascript 粘性标头不起作用?
- python - azure - Python - 分析法语文本。法语参数?
- html - 如果您添加以及获取它的脚本标签,您是否会获取两次数据?
- javascript - 怎么获得s并排
- javascript - 为游戏循环动画运行单独的画布动画
- javascript - 无法在 html 网页中显示文本文件的内容