Transmisión de una solicitud en asp.net (Reenviar una solicitud)


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 normal es que el remitente envía un HttpRequest a mi aplicación, y yo lo recibo en un HttpHandler. Esto a su vez envía el HttpContext a algún businesslogic para hacer algo de fontanería.

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

La pregunta es realmente - ¿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!

Author: John Sheehan, 2009-03-30

5 answers

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://stackoverflow.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();
    }
}
 32
Author: diachedelic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-04 16:28:05

En realidad, algo como esto 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();

Edit: el método ReadToByteArray simplemente crea una matriz de bytes a partir de la secuencia

 26
Author: El Che,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-04 16:27:42

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
 4
Author: Hafthor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-17 22:06:29

HttpContext incluye la propiedad Request, que a su vez contiene la colección Headers. Debería ser toda la información que necesitas.

 1
Author: John Saunders,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-30 13:43:53

Posiblemente algo como:

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

Luego llame a la respuesta get

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

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

 -1
Author: dkarzon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-31 03:50:52