Ретрансляция запроса в asp.net (пересылка запроса)
Автор вопроса: El CheОтветов: 5
У меня есть веб-приложение, которое взаимодействует между двумя разными веб-приложениями (один получатель и один отправитель, отправитель взаимодействует с моим приложением, а мое приложение взаимодействует с обоими).
Обычный сценарий заключается в том, что отправитель отправляет HttpRequest моему приложению, и я получаю его в HttpHandler. Это, в свою очередь, отправляет HttpContext в некоторую бизнес-логику, чтобы выполнить некоторые действия.
После того, как мои бизнес-классы закончили хранение данных (некоторые журналы и т. д.), я хочу передать тот же запрос со всеми заголовками, данными формы и т. д. в приложение-получатель. Это должно быть отправлено из класса, а не HttpHandler.
На самом деле вопрос в том, как я могу взять объект HttpContext и перенаправить/ретранслировать точно такой же запрос, только изменив URL-адрес с http://myserver.com/ на http://receiver.com.
Любые примеры кода в предпочтительном С# были бы замечательными!
У меня есть метод расширения на HttpResponseBase для копирования входящего запроса в исходящий запрос.
Использование:
var externalRequest = (HttpWebRequest)WebRequest.Create("http://stackoverflow.com");
this.Request.CopyTo(externalRequest);
var externalResponse = (HttpWebResponse)externalRequest.GetResponse();
Источник:
/// <summary>
/// Copies all headers and content (except the URL) from an incoming to an outgoing
/// request.
/// </summary>
/// <param name="source">The request to copy from</param>
/// <param name="destination">The request to copy to</param>
public static void CopyTo(this HttpRequestBase source, HttpWebRequest destination)
{
destination.Method = source.HttpMethod;
// Copy unrestricted headers (including cookies, if any)
foreach (var headerKey in source.Headers.AllKeys)
{
switch (headerKey)
{
case "Connection":
case "Content-Length":
case "Date":
case "Expect":
case "Host":
case "If-Modified-Since":
case "Range":
case "Transfer-Encoding":
case "Proxy-Connection":
// Let IIS handle these
break;
case "Accept":
case "Content-Type":
case "Referer":
case "User-Agent":
// Restricted - copied below
break;
default:
destination.Headers[headerKey] = source.Headers[headerKey];
break;
}
}
// Copy restricted headers
if (source.AcceptTypes.Any())
{
destination.Accept = string.Join(",", source.AcceptTypes);
}
destination.ContentType = source.ContentType;
destination.Referer = source.UrlReferrer.AbsoluteUri;
destination.UserAgent = source.UserAgent;
// Copy content (if content body is allowed)
if (source.HttpMethod != "GET"
&& source.HttpMethod != "HEAD"
&& source.ContentLength > 0)
{
var destinationStream = destination.GetRequestStream();
source.InputStream.CopyTo(destinationStream);
destinationStream.Close();
}
}
редактировать: метод ReadToByteArray просто создает массив байтов из потока
Ответ 3 · рейтинг 4 · Hafthor
Вот хороший код ретрансляции в VB.NET с использованием MVC.
Глобал.asax.vb
Public Class MvcApplication
Inherits System.Web.HttpApplication
Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
routes.MapRoute("Default", "{*s}", New With {.controller = "Home", .action = "Index"})
End Sub
Sub Application_Start()
RegisterRoutes(RouteTable.Routes)
End Sub
End Class
HomeController.vb
Option Explicit On
Option Strict On
Imports System.Net
<HandleError()> _
Public Class HomeController
Inherits System.Web.Mvc.Controller
Function Index(ByVal s As String) As ActionResult
Server.ScriptTimeout = 60 * 60
If Request.QueryString.ToString <> "" Then s = s + "?" + Request.QueryString.ToString
Dim req As HttpWebRequest = CType(WebRequest.Create("http://stackoverflow.com/" + s), HttpWebRequest)
req.AllowAutoRedirect = False
req.Method = Request.HttpMethod
req.Accept = Request.Headers("Accept")
req.Referer = Request.Headers("Referer")
req.UserAgent = Request.UserAgent
For Each h In Request.Headers.AllKeys
If Not (New String() {"Connection", "Accept", "Host", "User-Agent", "Referer"}).Contains(h) Then
req.Headers.Add(h, Request.Headers(h))
End If
Next
If Request.HttpMethod <> "GET" Then
Using st = req.GetRequestStream
StreamCopy(Request.InputStream, st)
End Using
End If
Dim resp As WebResponse = Nothing
Try
Try
resp = req.GetResponse()
Catch ex As WebException
resp = ex.Response
End Try
If resp IsNot Nothing Then
Response.StatusCode = CType(resp, HttpWebResponse).StatusCode
For Each h In resp.Headers.AllKeys
If Not (New String() {"Content-Type"}).Contains(h) Then
Response.AddHeader(h, resp.Headers(h))
End If
Next
Response.ContentType = resp.ContentType
Using st = resp.GetResponseStream
StreamCopy(st, Response.OutputStream)
End Using
End If
Finally
If resp IsNot Nothing Then resp.Close()
End Try
Return Nothing
End Function
Sub StreamCopy(ByVal input As IO.Stream, ByVal output As IO.Stream)
Dim buf(0 To 16383) As Byte
Using br = New IO.BinaryReader(input)
Using bw = New IO.BinaryWriter(output)
Do
Dim rb = br.Read(buf, 0, buf.Length)
If rb = 0 Then Exit Do
bw.Write(buf, 0, rb)
Loop
End Using
End Using
End Sub
End Class
Ответ 4 · рейтинг 1 · John Saunders
HttpContext включает свойство Request, которое, в свою очередь, содержит коллекцию заголовков. Это должна быть вся необходимая информация.