.net api代理
背景
存在数量较多需要中转调用的接口,不可能每个接口都定义实体然后转发,可以直接编写通用的代理服务。
特殊逻辑
如果存在需要移除的url参数可以使用RemoveParamFromQueryString移除,本文需要移除参数中的__EnvID,根据实际情况调整。
调用方法
继承AgentBaseController 后创建接口
/// <summary>
/// 无代码系统列表(系统下拉)
/// </summary>
[HttpGet]
[ApiIgnore]
public IActionResult GetSystemList([FromQuery] EnvAgentDto dto)
{
var envBaseUrl="http://127.0.0.1:7000";
var result = GetProxy("/api/NC/System/GetList", envBaseUrl);
return result;
}
/// <summary>
///
/// </summary>
[HttpPost]
[ApiIgnore]
public IActionResult GetTranslateValueInfo([FromQuery] EnvAgentDto dto)
{
var envBaseUrl="http://127.0.0.1:7000";
var result = PostProxy("/api/common/TranslateValue/GetTranslateValueInfo", envBaseUrl);
return result;
}
/// <summary>
///
/// </summary>
[HttpPost]
[ApiIgnore]
public IActionResult GetPageList([FromQuery] EnvAgentDto dto)
{
var env = sysEnvService.GetByID(dto.__EnvID);
ExceptionHelper.CheckNull(env, "EnvNull");
callerAgent.IsAlive(env.EnvCode);
var result = PostProxy("/api/NC/Page/GetList", env.EnvCfgAddress);
return result;
}
代理逻辑
public class AgentBaseController : ServerBaseController
{
private readonly string ContentType = "application/json; charset=utf-8";
//private readonly string ContextType ="application/json";
private readonly IHttpClientFactory _httpClientFactory;
public AgentBaseController(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
protected IActionResult GetProxy(string path, string baseUrl)
{
if (string.IsNullOrWhiteSpace(baseUrl))
return BadRequest(new { error = "Missing 'baseUrl' query parameter." });
var filteredQuery = RemoveParamFromQueryString(Request.QueryString, "__EnvID");
var targetUrl = $"{baseUrl.TrimEnd('/')}{path}{filteredQuery}";
var client = _httpClientFactory.CreateClient();
var requestMessage = new HttpRequestMessage(HttpMethod.Get, targetUrl);
CopyHeaders(requestMessage);
var response = client.SendAsync(requestMessage).Result;
var content = response.Content.ReadAsStringAsync().Result;
// 返回 JSON 格式,透传下游状态码
return new ContentResult
{
Content = content,
ContentType = ContentType,
StatusCode = (int)response.StatusCode
};
}
protected IActionResult PostProxy(string path, string baseUrl)
{
if (string.IsNullOrWhiteSpace(baseUrl))
return BadRequest(new { error = "Missing 'baseUrl' query parameter." });
Request.EnableBuffering();
string bodyContent;
using (var reader = new StreamReader(Request.Body, Encoding.UTF8, leaveOpen: true))
{
bodyContent = reader.ReadToEndAsync().Result;
Request.Body.Position = 0;
}
var filteredQuery = RemoveParamFromQueryString(Request.QueryString, "__EnvID");
var targetUrl = $"{baseUrl.TrimEnd('/')}{path}{filteredQuery}";
var client = _httpClientFactory.CreateClient();
var requestMessage = new HttpRequestMessage(HttpMethod.Post, targetUrl);
CopyHeaders(requestMessage);
requestMessage.Content = new StringContent(bodyContent, Encoding.UTF8, Request.ContentType ?? ContentType);
var response = client.SendAsync(requestMessage).Result;
var content = response.Content.ReadAsStringAsync().Result;
return new ContentResult
{
Content = content,
ContentType = ContentType,
StatusCode = (int)response.StatusCode
};
}
private static string RemoveParamFromQueryString(QueryString queryString, string paramName)
{
if (!queryString.HasValue)
return string.Empty;
var query = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(queryString.Value);
query.Remove(paramName);
var pairs = query.SelectMany(kv => kv.Value, (kv, v) => $"{kv.Key}={Uri.EscapeDataString(v)}");
return pairs.Any() ? "?" + string.Join("&", pairs) : string.Empty;
}
private void CopyHeaders(HttpRequestMessage requestMessage)
{
var excludedHeaders = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"Host", "Content-Length", "Transfer-Encoding", "Connection",
"Keep-Alive", "Upgrade", "Proxy-Authorization", "Proxy-Connection",
"TE", "Trailer"
};
foreach (var header in Request.Headers)
{
var key = header.Key;
if (excludedHeaders.Contains(key))
continue;
if (key.Equals("Content-Type", StringComparison.OrdinalIgnoreCase))
continue;
if (!requestMessage.Headers.TryAddWithoutValidation(key, header.Value.ToArray()))
{
// 忽略无法添加的头部
}
}
}
}
留待后查,同时方便他人
联系我:ivesbao@163.com
联系我:ivesbao@163.com

浙公网安备 33010602011771号