net asp c# .net http communication forwarding

c# - Retransmitir una solicitud en asp.net(reenviar una solicitud)



rest c# (5)

Aquí hay un buen código de retransmisión en VB.NET usando MVC.

GLOBAL.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

Tengo una aplicación web que se comunica entre dos aplicaciones web diferentes (un receptor y un remitente, el remitente se comunica con mi aplicación y mi aplicación se comunica con ambas).

Un escenario habitual es que el remitente envía una solicitud Http a mi aplicación, y la recibo en un HttpHandler. Esto, a su vez, envía el HttpContext a algunos businesslogic para hacer algo de plomería.

Después de que mis clases de negocio terminen de almacenar datos (algunos registros, etc.), deseo transmitir la misma solicitud con todos los encabezados, datos de formulario, etc. a la aplicación receptora. Esto debe enviarse desde la clase, y no desde HttpHandler.

La pregunta es en realidad: ¿cómo puedo tomar un objeto HttpContext y reenviar / retransmitir exactamente la misma solicitud, solo modificando la URL de http://myserver.com/ a http://receiver.com ?

¡Cualquier ejemplo de código en c # preferible sería genial!


En realidad, algo así funcionó bien

HttpRequest original = context.Request; HttpWebRequest newRequest = (HttpWebRequest)WebRequest.Create(newUrl); newRequest .ContentType = original.ContentType; newRequest .Method = original.HttpMethod; newRequest .UserAgent = original.UserAgent; byte[] originalStream = ReadToByteArray(original.InputStream, 1024); Stream reqStream = newRequest .GetRequestStream(); reqStream.Write(originalStream, 0, originalStream.Length); reqStream.Close(); newRequest .GetResponse();

editar: el método ReadToByteArray solo hace una matriz de bytes de la secuencia


HttpContext incluye la propiedad Request, que a su vez contiene la colección Headers. Debe ser toda la información que necesita.


Posiblemente algo como:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("www.testing.test"); request.Headers = (WebHeaderCollection)Request.Headers;

Luego llama a la respuesta get

HttpWebResponse response = (HttpWebResponse)request.GetResponse();

Esto tendrá los mismos encabezados HTTP que la solicitud original.


Tengo un método de extensión en HttpResponseBase para copiar una solicitud entrante a una solicitud saliente.

Uso:

var externalRequest = (HttpWebRequest)WebRequest.Create("http://.com"); this.Request.CopyTo(externalRequest); var externalResponse = (HttpWebResponse)externalRequest.GetResponse();

Fuente:

/// <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(); } }