C#MVC.Net控制器简化

时间:2018-09-21 19:33:41

标签: c# asp.net-mvc

我正在努力避免出现“胖控制器”的情况。

有许多控制器调用一个API的示例,但是如果您的控制器需要调用两个或多个API怎么办?

您如何简化这种情况?似乎应该有一种更清洁的方法:

private ServiceTwo serviceTwo = new ServiceTwo();
private MailService mailService = new MailService();

[HttpPost]
public async Task<ActionResult> Index(Customer formData) 
{
    if (!ModelState.IsValid) 
    {
        return View();
    }

    var apiOneService = new ApiOneService(formData);

    if (apiOneService.ExistingUserCheck()) 
    {
        ModelState.AddModelError("Email", "* Email address already exists.");
        return View(formData);
    }

    var apiTwoResult = serviceTwo.CreateTrial(formData);

    var emailResult = await mailService.SendMailAsync((formData));

    return RedirectToAction("Index", "TrialConfirmation");
}

3 个答案:

答案 0 :(得分:1)

对于这么小的东西,您可以将逻辑提取到控制器中的其他方法:

[HttpPost]
public async Task<ActionResult> Index(Customer formData) {
    if (!ModelState.IsValid) {
        return View();
    }

    var ok = await CreateTrial(formData);
    return ok 
        ? (ActionResult)RedirectToAction("Index", "TrialConfirmation")
        : View(formData);
    }
}

protected async Task<bool> CreateTrial(Customer formData) {
    var apiOneService = new ApiOneService(formData);
    if (apiOneService.ExistingUserCheck()) return false;

    var emailTask = mailService.SendMailAsync((formData));
    var apiTwoResult = serviceTwo.CreateTrial(formData);
    await emailTask;

    return true;
}

对于更复杂的方法,您也可以将逻辑提取到单独的类或层中。

答案 1 :(得分:0)

您可以简化控制器,直到:

https://github.com/DashboardCode/Routines/blob/master/AdminkaV1/Injected.AspCore.MvcApp/Controllers/UsersController.cs

在这里您只能看到元数据定义:什么是id,哪些字段需要加载数据(一对多,许多需要加载,依此类推)。

实际上,您是在问如何编写内部DSL,以“更大的砖块”定义我的控制器。只要写

可能但不能带来完全的满足。人们坚持使用通用代码,因为它是通用的。即使冗长。

答案 2 :(得分:-1)

在某些类似情况下,我倾向于实现服务层,并通过依赖注入公开接口。 逻辑在服务层中,控制器只是将此逻辑公开给视图。