How to set up Web API Routing for a Proxy Controller?

后端 未结 1 1230
情书的邮戳
情书的邮戳 2020-12-28 11:53

Part of my application needs to act as a Proxy Server for a third party RESTful web service. Is there a way to set up Web API routing so that all requests of the same type

1条回答
  •  礼貌的吻别
    2020-12-28 12:34

    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 Get(string url)
        {
        }
    
        public async Task Post(string url)
        {
        }
    
        public async Task Put(string url)
        {
        }
    
        public async Task Delete(string url)
        {
        }
    }
    

    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" });
    

    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 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);
        }
    }
    

    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

    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).

    0 讨论(0)
提交回复
热议问题