更新时间: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).