You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为多个ASP.NET Core Web API控制器消除重复代码?

移除ASP.NET Core Web API控制器重复代码的方案

针对你遇到的多控制器代码重复问题,推荐两种实用的解决方案,彻底消除冗余代码:

方案一:泛型基控制器

创建泛型基控制器封装所有通用逻辑,子类控制器仅需实现差异化的URL获取逻辑即可。

泛型基控制器代码

public abstract class BaseProxyController<TRequest> : Controller
{
    protected readonly HttpClient _httpClient;

    public BaseProxyController(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    // 抽象方法,由子类实现对应业务的配置URL获取
    protected abstract string GetProxyUrl();

    public async Task<JsonResult> GetAsync([FromBody] TRequest request)
    {
        // 这里放所有通用代码(参数校验、日志、前置处理等)
        
        var proxyUrl = GetProxyUrl();
        var jsonContent = new StringContent(
            JsonConvert.SerializeObject(request), 
            Encoding.UTF8, 
            "application/json");
        var response = await _httpClient.PostAsync(proxyUrl, jsonContent);
        
        // 这里放所有通用代码(响应解析、错误处理、结果封装等)
        var result = await response.Content.ReadAsStringAsync();
        return Json(result);
    }
}

改造后的OrdersController

public class OrdersController : BaseProxyController<ZoneRequest>
{
    public OrdersController(HttpClient httpClient) : base(httpClient)
    {
    }

    protected override string GetProxyUrl()
    {
        return FetchOrdersValFromConfigFile(); // 保留原有的URL获取逻辑
    }
}

public class ZoneRequest
{
    public string postCode { get; set; }
    public string suburb { get; set; }
}

改造后的PricesController

public class PricesController : BaseProxyController<ServiceRequest>
{
    public PricesController(HttpClient httpClient) : base(httpClient)
    {
    }

    protected override string GetProxyUrl()
    {
        return FetchPricesValFromConfigFile(); // 保留原有的URL获取逻辑
    }
}

public class ServiceRequest
{
    public string serviceName { get; set; }
    public string ClientCode { get; set; }
    public string ServiceCode { get; set; }
}

方案二:提取通用代理服务

如果不想依赖泛型基类,可以把通用请求逻辑抽离到独立服务中,控制器仅负责接收参数和调用服务,符合单一职责原则。

通用代理服务代码

public interface IApiProxyService
{
    Task<string> SendRequestAsync<TRequest>(TRequest request, string proxyUrl);
}

public class ApiProxyService : IApiProxyService
{
    private readonly HttpClient _httpClient;

    public ApiProxyService(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<string> SendRequestAsync<TRequest>(TRequest request, string proxyUrl)
    {
        // 这里放所有通用代码(参数校验、日志、前置处理等)
        
        var jsonContent = new StringContent(
            JsonConvert.SerializeObject(request), 
            Encoding.UTF8, 
            "application/json");
        var response = await _httpClient.PostAsync(proxyUrl, jsonContent);
        
        // 这里放所有通用代码(响应解析、错误处理、结果封装等)
        var result = await response.Content.ReadAsStringAsync();
        return result;
    }
}

改造后的OrdersController

public class OrdersController : Controller
{
    private readonly IApiProxyService _proxyService;

    public OrdersController(IApiProxyService proxyService)
    {
        _proxyService = proxyService;
    }

    public async Task<JsonResult> GetAsync([FromBody] ZoneRequest filterParameters)
    {
        var proxyUrl = FetchOrdersValFromConfigFile();
        var result = await _proxyService.SendRequestAsync(filterParameters, proxyUrl);
        return Json(result);
    }
}

改造后的PricesController

public class PricesController : Controller
{
    private readonly IApiProxyService _proxyService;

    public PricesController(IApiProxyService proxyService)
    {
        _proxyService = proxyService;
    }

    public async Task<JsonResult> GetAsync([FromBody] ServiceRequest req)
    {
        var proxyUrl = FetchPricesValFromConfigFile();
        var result = await _proxyService.SendRequestAsync(req, proxyUrl);
        return Json(result);
    }
}

补充说明

  • 关于DTO继承:你的场景中无需强制让DTO继承父类,泛型已经能适配不同参数类型。如果后续出现通用请求字段(如分页、鉴权信息),再让DTO继承BaseRequest基类即可。
  • 配置优化:如果FetchXXXValFromConfigFile这类方法也存在重复,可以把配置读取逻辑封装到统一的配置服务中,进一步减少冗余。

内容的提问来源于stack exchange,提问作者user419022

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 02:57:52