Reputation: 834
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?
Upvotes: 7
Views: 7487
Reputation: 25039
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. With time, its source code was deleted from AspLabs repo and now can be found only in its git history
This is the code actually forwarding a response, i.e. copying a received HttpResponseMessage
to the upstream HttpContext.Response
:
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);
}
Upvotes: 12
Reputation: 1503
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();
}
}
Upvotes: 1
Reputation: 699
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
Upvotes: 0