且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何为代理控制器设置 Web API 路由?

更新时间:2021-08-19 07:28:44

这是我如何让它工作的.首先,为您要支持的每个动词创建一个带有方法的控制器:

Here's how I got this to work. First, create a controller with a method for each verb you want to support:

public class ProxyController : ApiController
{
    private Uri _baseUri = new Uri("http://otherwebservice.com");

    public async Task<HttpResponseMessage> Get(string url)
    {
    }

    public async Task<HttpResponseMessage> Post(string url)
    {
    }

    public async Task<HttpResponseMessage> Put(string url)
    {
    }

    public async Task<HttpResponseMessage> Delete(string url)
    {
    }
}

这些方法是异步的,因为它们将使用 HttpClient.像这样映射您的路线:

The methods are async because they're going to use an HttpClient. Map your route like this:

config.Routes.MapHttpRoute(
  name: "Proxy",
  routeTemplate: "api/Proxy/{*url}",
  defaults: new { controller = "Proxy" });

现在回到控制器中的 Get 方法.创建一个 HttpClient 对象,使用适当的 Url 创建一个新的 HttpRequestMessage 对象,从原始请求消息中复制所有(或几乎所有),然后调用 SendAsync():

Now back to the Get method in the controller. Create an HttpClient object, create a new HttpRequestMessage object with the appropriate Url, copy everything (or almost everything) from the original request message, then call SendAsync():

public async Task<HttpResponseMessage> Get(string url)
{
    using (var httpClient = new HttpClient())         
    {
        string absoluteUrl = _baseUri.ToString() + "/" + url + Request.RequestUri.Query;
        var proxyRequest = new HttpRequestMessage(Request.Method, absoluteUrl);
        foreach (var header in Request.Headers)
        {
            proxyRequest.Headers.Add(header.Key, header.Value);
        }

        return await httpClient.SendAsync(proxyRequest, HttpCompletionOption.ResponseContentRead);
    }
}

结合 的 URL 可能更复杂,但这是基本思想.对于 Post 和 Put 方法,您还需要复制请求正文

The URL combining could be more sophisticated, but that's the basic idea. For the Post and Put methods, you'll also need to copy the request body

另外请注意在SendAsync调用中传递的HttpCompletionOption.ResponseContentRead参数,因为如果没有它,如果内容是大(就我而言,它将 500KB 100 毫秒的请求更改为 60 秒的请求).

Also please note a HttpCompletionOption.ResponseContentRead parameter passed in SendAsync call, because without it, ASP.NET will spend an exremeley long time reading the content if the content is large (in my case, it changed a 500KB 100ms request into a 60s request).