Как запретить моему клиенту .NET SOAP включать «Connection: KeepAlive» в заголовки HTTP. (используя WSE3.0) - PullRequest
6 голосов
/ 06 октября 2009

В заголовке HTTP-соединения мой клиент веб-службы включает: Connection: Keep-Alive

Я хочу отключить это. После некоторого исследования кажется, что способ сделать это состоит в том, чтобы установить для члена KeepAlive класса SoapHttpChannelOptions значение false. Но я не вижу способа доступа / изменения SoapHttpChannelOptions в классе клиента веб-сервиса , который был сгенерирован для меня в Visual Studio с использованием WSE3.0 (расширение веб-службы.

В моем случае сгенерированный класс заглушки расширяется Microsoft.Web.Services3.WebServicesClientProtocol

Мне не удалось найти ни одного примера поиска в Google, и большинство членов класса SoapHttpChannelOptions наследуются в классе WebServicesClientProtocol ...

Справочник по SoapHttpChannelOptions
Справочник по WebServicesClientProtocol

Примечание: я не пытаюсь изменить веб-сервер. Я пытаюсь изменить клиент веб-службы.

1 Ответ

11 голосов
/ 07 октября 2009

Одним из решений является переопределение метода GetWebRequest(Uri uri).
Информация, которая привела меня к этому решению, была найдена в этом MSDN сообщении на форуме

Способ 1. Изменение автоматически созданного файла.

Вставьте этот фрагмент в файл Reference.cs, который был автоматически сгенерирован для вас. Недостатком этого подхода является то, что если вы когда-нибудь заново создадите клиентские адаптеры веб-службы (т. Е. Обновите веб-ссылки), вам придется снова изменить файл.

protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
    System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)base.GetWebRequest(uri);
    webRequest.KeepAlive = false;
    return webRequest;
}

Метод 2: Создать частичный класс

Создайте файл и вставьте в него следующий код. Измените пространство имен и имя класса, чтобы они соответствовали вашему веб-сервису.

namespace YourNamespace
{
    using System.Diagnostics;
    using System.Web.Services;
    using System.ComponentModel;
    using System.Web.Services.Protocols;
    using System;
    using System.Xml.Serialization;

    /// <summary>
    /// This partial class makes it so all requests specify
    /// "Connection: Close" instead of "Connection: KeepAlive" in the HTTP headers.
    /// </summary>
    public partial class YourServiceNameWse : Microsoft.Web.Services3.WebServicesClientProtocol
    {
        protected override System.Net.WebRequest GetWebRequest(Uri uri)
        {
            System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)base.GetWebRequest(uri);
            webRequest.KeepAlive = false;
            return webRequest;
        }
    }
}

Примечания

Этот подход может работать, если вы не используете WSE. Я смог вставить вышеописанный метод в класс веб-сервиса, не относящийся к WSE ... который расширяет System.Web.Services.Protocols.SoapHttpClientProtocol. Из моего тестирования выяснилось, что из-за этого в нем вообще не было ни одной строки соединения Http, тогда как когда я делал это внутри класса WSE (производного от Microsoft.Web.Services3.WebServicesClientProtocol), он включал строку «Connection: Close». По данным этого сайта по HTTP KeepAlive :

Под HTTP 1.1, официальный keepalive метод отличается. Все соединения остаются в живых, если не указано в противном случае со следующим заголовком: Подключение: закрыть

Итак, хотя он может больше не включать KeepAlive в заголовок ... Я думаю, что в HTTP1.1 предполагается, что он используется по умолчанию.

...