简体   繁体   中英

How do I copy a HttpRequest to another web service?

I have two identical web services currently installed on the same PC for testing purposes. A request that is received by the first service, is suposed go to the second one as well. My intention was to do this using a HttpModule. I handle the request during application.BeginRequest.

public void AsyncForwardRequest(HttpRequest request)
{
    try
    {
        // Prepare web request...
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(WSaddress);

        req.Credentials = CredentialCache.DefaultCredentials;
        req.Headers.Add("SOAPAction", request.Headers["SOAPAction"]);
        req.ContentType = request.Headers["Content-Type"];
        req.Accept = request.Headers["Accept"];
        req.Method = request.HttpMethod;

        // Send the data.
        long posStream = request.InputStream.Position;
        long len = request.InputStream.Length;
        byte[] buff = new byte[len];
        request.InputStream.Seek(0, SeekOrigin.Begin);
        if (len < int.MaxValue && request.InputStream.Read(buff, 0, (int)len) > 0)
        {
            using (Stream stm = req.GetRequestStream())
            {
                stm.Write(buff, 0, (int)len);
            }

            request.InputStream.Position = posStream;
            DebugOutputStream(request.InputStream);
            request.InputStream.Seek(0, SeekOrigin.Begin);

            IAsyncResult result = (IAsyncResult)req.BeginGetResponse(new AsyncCallback(RespCallback), req);
        }
    }
    catch (Exception ex)
    {

        App.Error2(String.Format("RequestDuplicatorModule - BeginRequest; ERROR begin request: {0}", ex.Message), ex);
    }

private static void RespCallback(IAsyncResult asynchronousResult)
{
    try
    {
        // State of request is asynchronous.
        var req = (HttpWebRequest)asynchronousResult.AsyncState;
        WebResponse resp = (HttpWebResponse)req.EndGetResponse(asynchronousResult);

        Stream responseStream = resp.GetResponseStream();
        System.IO.Stream stream = responseStream;
        Byte[] arr = new Byte[1024 * 100];
        stream.Read(arr, 0, 1024 * 100);
        if (arr.Length > 0)
        {
            string body = (new ASCIIEncoding()).GetString(arr);
            Debug.Print(body);
        }
    }
    catch (WebException ex)
    {
        App.Error2(String.Format("RequestDuplicatorModule - BeginRequest; ERROR begin request: {0}", ex.Message), ex);
    }

}

This (HttpWebResponse)req.EndGetResponse(asynchronousResult) throws an exception: 500 Internal Server Error and fails. The original request goes through fine.

request.InnerStream: ...

Does this have anything to do with the web service addresses being different? In my case they're: http://localhost/WS/service.asmx http://localhost/WS_replicate/service.asmx

I would at least implement this, to be able to read the content of a httpwebrequest that has a status 500:

catch (WebException ex)
{
    HttpWebResponse webResponse = (HttpWebResponse)ex.Response;
    Stream dataStream = webResponse.GetResponseStream();

    if (dataStream != null)
    {
        StreamReader reader = new StreamReader(dataStream);
        response = reader.ReadToEnd();
    }
}

Not answering your question though, i would suggest having a simple amsx that reads the request, and posts the request to the two different web services. If you need some code for that let me know.

Additional advantages would be that the asmx will be easier to support for the developer as well as the one dealing with the deployment. You could add configuration options to make the actual url's dynamic.

Was able to modify the AsyncForwardRequest method so that I can actually edit the SoapEnvelope itself:

string buffString = System.Text.UTF8Encoding.UTF8.GetString(buff);

using (Stream stm = req.GetRequestStream())
{
    bool stmIsReadable = stm.CanRead;  //false, stream is not readable, how to get
                                       //around this?
                                       //solution: read Byte Array into a String,
                                       //modify <wsa:to>, write String back into a
                                       //Buffer, write Buffer to Stream

    buffString = buffString.Replace("http://localhost/WS/Service.asmx", WSaddress);

    //write modded string to buff
    buff = System.Text.UTF8Encoding.UTF8.GetBytes(buffString);

    stm.Write(buff, 0, (int)buff.Length);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM