Как скопировать HttpRequest в другой веб-сервис? - PullRequest
3 голосов
/ 30 ноября 2011

В настоящее время на одном компьютере установлены два идентичных веб-сервиса для тестирования. Запрос, полученный первой службой, переходит также и ко второй. Мое намерение было сделать это с помощью HttpModule. Я обрабатываю запрос во время подачи заявки. 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);
    }

}

Это (HttpWebResponse) req.EndGetResponse (asynchronousResult) выдает исключение: 500 Internal Server Error и происходит сбой. Исходный запрос проходит нормально.

request.InnerStream: ...

Это имеет какое-либо отношение к отличающимся адресам веб-службы? В моем случае они: http://localhost/WS/service.asmx http://localhost/WS_replicate/service.asmx

Ответы [ 2 ]

1 голос
/ 30 ноября 2011

Я бы по крайней мере реализовал это, чтобы иметь возможность читать содержимое httpwebrequest со статусом 500:

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

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

Не отвечая на ваш вопрос, я бы посоветовал иметь простой amsx, который читает запрос и отправляет запрос в два разных веб-сервиса. Если вам нужен код для этого, дайте мне знать.

Дополнительные преимущества заключаются в том, что asmx будет проще поддерживать как для разработчика, так и для разработчика. Вы можете добавить параметры конфигурации, чтобы сделать динамический URL-адрес.

0 голосов
/ 02 декабря 2011

Был в состоянии изменить метод AsyncForwardRequest, чтобы я мог на самом деле редактировать сам SoapEnvelope:

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