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