40

2 つの異なる Web アプリケーション間で通信する Web アプリケーションがあります (1 つの受信者と 1 つの送信者、送信者はアプリケーションと通信し、アプリケーションは両方と通信します)。

通常のシナリオでは、送信者が HttpRequest をアプリケーションに送信し、それを HttpHandler で受信します。これにより、HttpContext が何らかのビジネスロジックに送信され、配管が行われます。

ビジネスクラスがデータの保存 (ロギングなど) を完了した後、すべてのヘッダー、フォームデータなどを含む同じリクエストをレシーバーアプリケーションに中継したいと考えています。これは、HttpHandler からではなく、クラスから送信する必要があります。

問題は本当に - どうすれば HttpContext オブジェクトを取得し、URL をhttp://myserver.com/からhttp://receiver.comに変更するだけでまったく同じリクエストを転送/中継できるかです。

好ましい c# のコード例は素晴らしいでしょう!

4

5 に答える 5

42

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();
    }
}
于 2012-09-20T04:31:08.743 に答える
28

実際、このようなものはうまくいきました

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

編集: ReadToByteArray メソッドは、ストリームからバイト配列を作成するだけです

于 2009-03-31T06:39:47.587 に答える
4

MVC を使用した VB.NET の優れたリレー コードを次に示します。

グローバル.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

ホームコントローラー.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
于 2009-08-17T22:06:29.533 に答える
1

HttpContextにはRequestプロパティが含まれ、RequestプロパティにはHeadersコレクションが含まれます。それはあなたが必要とするすべての情報でなければなりません。

于 2009-03-30T13:43:53.473 に答える
-1

おそらく次のようなものです:

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

次に、get レスポンスを呼び出します

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

これには、元のリクエストと同じ HTTP ヘッダーが含まれます。

于 2009-03-31T03:50:52.873 に答える