首页 > 解决方案 > Net Core 自定义控制器

问题描述

目前我的代码看起来像这样:

public class UserController : ControllerBase
{

    [HttpPost]
    public async Task<ActionResult> Login(LoginCredentialsModel model)
    {
       if (someValidLogic){
           return Ok(new { message = "User login success.", 
                           additionalParameters = new { 
                                    param1 = "",
                                    param2 = ""
                            }
                          });
       }
        else {
           return BadRequest(new { errorMessage = "Username or password is incorrect.", 
                                   additionalParameters = {
                                       StatusCode = 400, 
                                       RetryLeftCount = 3 }
                                   });
        }  
    }

}

我正在手动创建 JSON 对象以在每个端点返回 UI,以便我可以进行一致的通信并允许 UI 在全局级别处理消息。(在我的情况下使用角度拦截器)。我想创建一个自定义类,该类可以由只有两个返回类型选项的所有控制器实现 - Success()、Fail()。

public class UserController : CustomControllerBase
{

    [HttpPost]
    public async Task<ActionResult> Login(LoginCredentialsModel model)
    {
       if (someValidLogic){
           return Success("User login success.", additionalParameters)
       }
       else {
           return Error("Username or password is incorrect.", additionalParameters);
       }  
    }

}

我的 CustomControllerBase 将负责以正确的形式格式化结果。我知道我可以通过中间件来做到这一点,但我真的不想这样做,因为它仍然允许开发人员意外地发回一些无效的结果并且中间件不知道如何处理它。

标签: c#asp.net.net-core

解决方案


即使您制作了自定义基础控制器,您也必须让自定义基础控制器扩展 Microsoft.AspNetCore.Mvc.ControllerBase,否则您将无法获得所有自动路由、[HttpPost] 类型属性等。你扩展了 ControllerBase,所有像 Ok() 这样的方法都将提供给你的其他开发人员。我真的只是尝试与开发人员沟通不要使用 Ok() 等。

这是 hacky,但您可以通过在您的 CustomControllerBase 中覆盖它们并抛出异常来“阻止”其他方法。这不会产生编译时错误,但至少会产生浅运行时异常。还有很多这些方法,您必须全部覆盖它们。

public class CustomControllerBase : ControllerBase
{
    public ActionResult Success(string message)
    {
        return base.Ok(message);
    }
    public new ActionResult Ok(object value)
    {
        throw new Exception("don't use this");
    }
}

public class UserController : CustomControllerBase
{

    public async Task<ActionResult> Hello()
    {
        return Ok("hello"); // throws runtime exception
    }
}

或者使用样式检查器并禁止所有使用 Ok() 和类似方法。你还必须禁止这样的行return new OkObjectResult("hello"); ,要做到这一点真的会是一个相当大的考验。


推荐阅读