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?
Send HTTP Response is a synchronous activity that sends a response to a previously received HTTP request. This activity is used in conjunction with the HTTP Receiver process starter activity and the Wait for HTTP Request activity. The default status line returned by this activity is " 200 OK ".
What is HttpClient? HttpClient class provide a base class that is used to send HTTP request and receive HTTP response resources. HttpClient sends and receives data from Web API URL which is hosted on the local IIS server. HttpClient can process multiple requests concurrently. [Install HttpClient Library]
HTTP Response broadly has 3 main components: Status Line. Headers. Body (Optional)
Look at aspnet/AspLabs 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 a 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);
}
There is full code copying a received HttpResponseMessage
to the HttpContext.Response
in the repository.
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();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With