简体   繁体   English

API controller 中的业务逻辑

[英]Business logic in the API controller

I have this method in my ClientsController:我的 ClientsController 中有这个方法:

//POST api/v1/clients
[HttpPost]
public async Task<ActionResult> CreateClient([FromBody] CreateClientDto createClientDto)
{
    await _createClientService.Create(createClientDto.MapToClient());
    return CreatedAtRoute("GetClient", new { clientId = createClientDto.ClientId });
}

As you can see, this method references a previously injected service.如您所见,此方法引用了先前注入的服务。 The service looks like this:该服务如下所示:

public class CreateClientServiceImpl : ICreateClientService
{
    private readonly ConfigurationDbContext configurationDbContext;

    public CreateClientServiceImpl(ConfigurationDbContext configurationDbContext)
    {
        this.configurationDbContext = configurationDbContext;
    }

    public async Task Create(Client client)
    {
        await configurationDbContext.Clients.AddAsync(client.ToEntity());
        await configurationDbContext.SaveChangesAsync();
    }
}

This is where the problem arises.这就是问题出现的地方。 Where will I check if the clientId exists?我将在哪里检查 clientId 是否存在? I think not in the ICreateClientService because it would violate the Single Responsibility Principle rule.我认为不在 ICreateClientService 中,因为它会违反单一责任原则规则。 I can create next service which will check if the user exists and use it in controller method, but I think it will be too many logic in controller method.我可以创建下一个服务来检查用户是否存在并在 controller 方法中使用它,但我认为 controller 方法中的逻辑太多了。 What should I do then?那我该怎么办? To be sure, ClientId is not an incremental Id, but too is unique.可以肯定的是,ClientId 不是增量 Id,但也是唯一的。

First answer this question: How do your application to react, if a client already exists?首先回答这个问题:如果客户端已经存在,您的应用程序将如何反应?

Also, are you aware of the fact that SaveChangesAsync() can throw a DbUpdateException or DbUpdateConcurrencyException ?另外,您是否知道SaveChangesAsync()可以抛出DbUpdateExceptionDbUpdateConcurrencyException的事实? Currently, you are not handling these cases.目前,您没有处理这些情况。

One possibility would be to introduce an exception, for example DuplicateClientException and throw this exception in your CreateClientServiceImpl.Create method, if this client already exists.一种可能性是引入异常,例如DuplicateClientException并在您的CreateClientServiceImpl.Create方法中抛出此异常(如果此客户端已存在)。 Another option is that Create returns a bool, indicating whether the create statement was successful.另一种选择是Create返回一个布尔值,指示 create 语句是否成功。 It could return false if it failed (one reason could be, that the client already exists).如果失败,它可能会返回 false(一个原因可能是客户端已经存在)。 You could also return a Result -object.您还可以返回一个Result对象。 There is a library by Ardelis, see Result , which offers a solution to the problem you have. Ardelis 有一个库,请参阅Result ,它为您遇到的问题提供了解决方案。

Your controller method can then handle the exception, translate the method return value as you see fit or (automatically) turn the Result object into the correct status code, for example a 400 Bad Request .然后,您的 controller 方法可以处理异常,转换您认为合适的方法返回值或(自动)将Result object 转换为正确的状态代码,例如400 Bad Request

Right now, I believe your code would run into an exception, if you have your primary keys set up correctly, and your controller would return a 500 Internal Server Error .现在,如果您的主键设置正确,我相信您的代码会遇到异常,并且您的 controller 将返回500 Internal Server Error If this is the behavior you want, then you don't have to change anything.如果这是您想要的行为,那么您无需更改任何内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM