问题
I have a client (Xamarin) and two Web API servers, A and B. The client makes a request to A which uses the request parameters to make another request to B. How do I return the response that A receives from B to the client such that B's use of C is transparent to the client.
For example, if I make a request from A to B using HttpClient how do I forward the HttpResponseMessage to the client in a controller's action?
回答1:
Look at the Microsoft ASP.NET Core Proxy repository for a good example of a transparent HTTP proxy. This proxy is a middleware handling client's requests to A and making its own requests to B.
To provide a complete answer, this is the part of its source code which is actually forwarding the HttpResponseMessage:
using (var responseMessage = await _httpClient.SendAsync(
requestMessage, HttpCompletionOption.ResponseHeadersRead, context.RequestAborted))
{
context.Response.StatusCode = (int)responseMessage.StatusCode;
foreach (var header in responseMessage.Headers)
{
context.Response.Headers[header.Key] = header.Value.ToArray();
}
foreach (var header in responseMessage.Content.Headers)
{
context.Response.Headers[header.Key] = header.Value.ToArray();
}
// SendAsync removes chunking from the response. This removes the header so it doesn't expect a chunked response.
context.Response.Headers.Remove("transfer-encoding");
await responseMessage.Content.CopyToAsync(context.Response.Body);
}
Update from 2019: The proxy was totally re-designed after the original answer had been published. This is the updated code copying a received HttpResponseMessage to the HttpContext.Response. Moreover, the whole project was archived a bit later. Check the repository readme to get more info about ongoing development.
回答2:
this is a Server Side:
WebForm1.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
HttpClient client = new HttpClient();
client.Timeout = TimeSpan.FromSeconds(10);
client.GetAsync("http://localhost:14388/WebForm2.aspx").ContinueWith(
getTask =>
{
if (getTask.IsCanceled)
{
Console.WriteLine("Request was canceled");
}
else if (getTask.IsFaulted)
{
Console.WriteLine("Request failed: {0}", getTask.Exception);
}
else
{
HttpResponseMessage response = getTask.Result;
string _message = response.Content.ReadAsStringAsync()
.Result
.Replace("\\", "")
.Trim(new char[1] { '"' });
}
});
}
WebForm2.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="Volkan.WebForm2" %>
WebForm2.aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("ahada cevabım");
}
this is a Client side: https://stackoverflow.com/a/38218387/2797185
回答3:
I took IIya's answer and adapted it for asp.net MVC 5
public async Task GetFile(CancellationToken cancellationToken)
{
var context = HttpContext;
var _httpClient = StaticHttpClient.Instance;
var requestMessage = new HttpRequestMessage()
{
RequestUri = new Uri("https://localhost:44305/api/files/123"),
};
using (var responseMessage = await _httpClient.SendAsync(
requestMessage, HttpCompletionOption.ResponseHeadersRead, cancellationToken))
{
Response.StatusCode = (int)responseMessage.StatusCode;
foreach (var header in responseMessage.Headers)
{
Response.Headers[header.Key] = header.Value.First();
}
foreach (var header in responseMessage.Content.Headers)
{
Response.Headers[header.Key] = header.Value.First();
}
Response.Headers.Remove("transfer-encoding");
//Response.BinaryWrite(await responseMessage.Content.ReadAsByteArrayAsync());
await responseMessage.Content.CopyToAsync(Response.OutputStream);
Response.Flush();
Response.Close();
context.ApplicationInstance.CompleteRequest();
}
}
来源:https://stackoverflow.com/questions/44729592/how-to-forward-http-response-to-client