我不确定这个问题是否符合这个论坛的目的,但我也不认为它应该属于堆栈溢出问题,所以下面是这样说的:
我创建了一个模型绑定,通过将它放入模型绑定本身,使一个映射变得“干净”,但现在我想用另一种操作方法再次这样做,我只是想知道是否会有更好的方法来实现它,因为我不认为这是正确的地方。
我的动作方法如下所示:
[HttpPost("Register")]
public async Task<IActionResult> Register(
[FromQuery] UserToRegister userToRegister,
User user /*This property is never used from the body request, since I set it in my custom Model Binder*/)
{
var response = await _userService.RegisterAsync(user);
return Ok(response);
}我创建了一个定制的Model,其中我将属性从userToRegister映射到user param。这个定制的活页夹看起来是这样的:
public Task BindModelAsync(ModelBindingContext bindingContext)
{
var values = bindingContext.ValueProvider;
User user = new User()
{
Id = Guid.NewGuid(),
Name = values.GetValue("Name").FirstValue,
Password = /*password encrypted*/,
...
};
bindingContext.Result = ModelBindingResult.Success(user);
return Task.CompletedTask;
}你觉得这是个好办法吗?在请求中获取User对象更好,这样我可以稍后修改它吗?我是否应该在ModelBinder中进行此修改(哈希密码、创建新Id等)?
发布于 2020-05-29 17:41:02
自定义模型绑定正在取代应用程序中的用例。虽然这在技术上是可行的,但对于大多数人来说,发现这种逻辑深深地隐藏在UI层的架构中是令人惊讶的。此外,您无法利用默认模型绑定器获得的自动数据转换。
您当前的用例似乎只处理字符串,所以这里没有什么大不了的。当用例需要编号或日期时,您将不得不编写手动转换代码,迫使您编写一堆在使用默认模型绑定时不需要编写的锅炉板代码。
我对这类事情一直有点怀疑。它开始变成小鸡巫毒魔法,因为从控制器代码中看不出用例是如何执行的。最小惊讶原则在这里适用。我不希望在这里执行业务用例。这方面的共同之处是:
我并不是在判断上述任何一种做法是否是最佳做法。这些只是常见的发现这种行为的地方。
基本上,我希望控制流会像这样:
Browser -> HTTP Request -> MVC framework -> controller -> ??? -> business class您可以将???替换为可以追溯到控制器启动的方法调用的东西。
发布于 2021-06-23 18:18:23
除非逻辑非常复杂,否则控制器没有理由不能执行映射。
[HttpPost("Register")]
public async Task<IActionResult> Register([FromQuery] UserToRegister userToRegister)
{
var user = new User {
Name = userToRegister.Name,
Email = userToRegister.Email
};
var response = await _userService.RegisterAsync(user);
return Ok(response);
}该代码类型安全,易于理解,并将映射逻辑的代码保存在映射发生的地方附近。所以这是一个很好的默认选择。
如果逻辑非常复杂,可以编写实用程序类或实用程序方法来执行映射;例如,可以为UserToRegister类提供一个ToUser()方法。或者你可以使用像AutoMapper这样的工具。但是,除非您的映射逻辑导致操作方法变得太大,难以理解,否则我不会操心。
https://softwareengineering.stackexchange.com/questions/410747
复制相似问题