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

C#开发支持GET/POST/DELETE的网关Web API需求

C# 实现支持GET/POST/DELETE的网关Web API

需要编写一个网关Web API,支持GET、POST、DELETE请求,接收目标子域名、目标请求方法和原始HttpRequest作为输入,将请求转发到对应子域名的目标服务,并返回目标服务的完整响应。

优化后的完整实现代码

using Microsoft.AspNetCore.Mvc;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

[ApiController]
[Route("api/gateway")]
public class GatewayController : ControllerBase
{
    private readonly IHttpClientFactory _httpClientFactory;

    // 通过依赖注入复用HttpClient实例,避免套接字资源耗尽
    public GatewayController(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }

    // 支持GET、POST、DELETE三种请求方法
    [HttpGet]
    [HttpPost]
    [HttpDelete]
    public async Task<IActionResult> ForwardRequest(string targetSubdomain, string targetMethod)
    {
        // 拼接目标服务的完整请求地址(保留原始请求的路径和查询参数)
        var targetUrl = $"https://{targetSubdomain}{Request.Path}{Request.QueryString}";
        
        // 创建转发用的请求消息
        using var requestMessage = new HttpRequestMessage(new HttpMethod(targetMethod), targetUrl);

        // 复制原始请求的请求头(自动跳过无法转发的头字段)
        foreach (var header in Request.Headers)
        {
            if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()) && requestMessage.Content != null)
            {
                requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
            }
        }

        // 处理带请求体的请求(如POST)
        if (Request.ContentLength > 0 && !string.IsNullOrEmpty(Request.ContentType))
        {
            var content = new StreamContent(Request.Body);
            content.Headers.ContentType = MediaTypeHeaderValue.Parse(Request.ContentType);
            requestMessage.Content = content;
        }

        // 获取复用的HttpClient实例并发送请求
        var httpClient = _httpClientFactory.CreateClient();
        var response = await httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead);

        // 原样返回目标服务的响应(状态码、响应头、响应内容)
        var responseContent = await response.Content.ReadAsStreamAsync();
        var result = new FileStreamResult(responseContent, response.Content.Headers.ContentType?.MediaType);
        result.StatusCode = (int)response.StatusCode;
        
        foreach (var header in response.Headers)
        {
            Response.Headers.TryAdd(header.Key, header.Value.ToArray());
        }
        
        foreach (var header in response.Content.Headers)
        {
            Response.Headers.TryAdd(header.Key, header.Value.ToArray());
        }

        return result;
    }
}

关键实现说明

  • HttpClient复用:使用IHttpClientFactory注入,避免频繁创建HttpClient导致的套接字资源泄漏,这是ASP.NET Core官方推荐的最佳实践。
  • 完整请求转发:保留原始请求的路径、查询参数、请求头和请求体,支持JSON、表单、二进制等多种媒体类型。
  • 响应原样返回:完全复用目标服务的响应状态码、响应头和响应内容,确保客户端能获取到完整的服务反馈。
  • 请求头兼容处理:自动跳过无法转发的头字段,避免出现无效请求的情况。

依赖配置(Program.cs)

在项目的Program.cs中添加HttpClientFactory服务:

var builder = WebApplication.CreateBuilder(args);

// 注册HttpClientFactory服务
builder.Services.AddHttpClient();

builder.Services.AddControllers();
// 其他服务配置...

var app = builder.Build();

// 中间件配置...

app.MapControllers();

app.Run();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 19:44:59