Ищете способ переопределить метод GetResponseStream HttpWebResponse

Я ищу способ переопределить метод GetResponseStream класса HttpWebResponse, чтобы вернуть пользовательский поток. По сути, моя цель - изменить поток. Не уверены, что это возможно? Это делается в контексте интеграции с веб-службой, и мне нужно удалить часть контента из потока ответов. есть идеи?


person Bukhatir    schedule 24.09.2013    source источник
comment
Нет, я не верю, что это возможно. Однако очень неясно, какова ваша архитектура - не можете ли вы обернуть веб-службу в API, который делает правильные вещи? Вам действительно нужно выставлять необработанный поток в любом случае?   -  person Jon Skeet    schedule 25.09.2013
comment
к сожалению, у меня нет доступа к веб-сервису, и его нельзя изменить.   -  person Bukhatir    schedule 25.09.2013
comment
Нет, я говорил о том, чтобы сделать это на стороне клиента. Вы действительно не дали нам много контекста здесь ...   -  person Jon Skeet    schedule 25.09.2013
comment
@JonSkeet: На самом деле, для этого вы можете использовать глубоко злые хаки; Я попробовал это один раз и преуспел. (зарегистрируйте собственный обработчик протокола для своего доменного имени и вызовите устаревший ctor сериализации)   -  person SLaks    schedule 25.09.2013
comment
@SLaks: я надеюсь, что ОП ищет что-то не очень злое :)   -  person Jon Skeet    schedule 25.09.2013
comment
здесь упоминается что-то подобное, но не указано, как именно переопределить метод getresponsestream -a-string" title="soaphttpclientprotocol получить ответ в виде потока вместо строки"> stackoverflow.com/questions/5011823/   -  person Bukhatir    schedule 25.09.2013
comment
@Bukhatir: Еще раз: как вы используете веб-сервис?   -  person SLaks    schedule 25.09.2013
comment
используя WSE 3.0 (прокси, сгенерированный VS), я знаю, что меня попросят перейти по маршруту wcf, но это не вариант :(   -  person Bukhatir    schedule 25.09.2013


Ответы (3)


Я ищу способ переопределить метод GetResponseStream класса HttpWebResponse, чтобы вернуть пользовательский поток.

Прохладно. GetResponseStream в любом случае виртуальный, так что вперед , переопределите его и верните все, что хотите. Конечно, вам придется проектировать свой код таким образом, чтобы вы не работали с конкретными реализациями класса HttpWebResponse, что бывает редко. Потому что обычно вы получаете экземпляр HttpWebResponse из HttpWebRequest. Так что это тесная связь. Поэтому начните думать о том, как вы можете абстрагировать весь этот HTTP-материал в своем коде. Я имею в виду, перестаньте думать с точки зрения HttpWebRequests. Начните думать с точки зрения интерфейсов и абстракций в вашем коде. Это то, что вас в любом случае спасет, и это то, что ослабит связь между различными слоями вашего кода и сделает его пригодным для модульного тестирования.

Смысл этого ответа в том, что ваш код должен быть разработан таким образом, чтобы он не зависел от каких-либо конкретных классов HttpWebRequest. Вы должны начать думать о том, чтобы скрыть это за абстракцией интерфейса, которую вы могли бы легко смоделировать в своем модульном тесте.

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

person Darin Dimitrov    schedule 24.09.2013
comment
Но это требует создания подкласса HttpWebResponse для начала... тогда как экземпляр обычно создается внутренностями фреймворка (в WebRequest.GetResponse и т. д.). Можете ли вы привести пример того, как вы могли бы переопределить его и использовать? (Может быть, есть механизм плагинов, который у меня никогда не было причин использовать раньше...) - person Jon Skeet; 25.09.2013
comment
Да, это то, что требуется. Вот почему вы не должны полагаться на какие-либо конкретные вещи контекста HTTP, такие как HttpWebRequests в коде. И нет, я все равно никогда не переопределю методы GetResponseStream. Это было бы совершенно безумием. Я бы спрятал всю зависимость от материала HttpWebrequest за абстракцией интерфейса, которую я мог бы более чем счастливо высмеять в своем модульном тесте. - person Darin Dimitrov; 25.09.2013

Вы не можете легко изменить поведение HttpWebResponse. Либо вы обертываете API веб-сервиса на стороне клиента, как предложил @Jon в комментарии, либо, если вы действительно хотите приключений, измените запрос, указав его на прокси-сервер, который будет изменить поток по мере необходимости.

Однако это не будет банально.

person zmbq    schedule 24.09.2013

Предполагая, что вы можете изменить код, вызывающий GetResponseStream, шаблон адаптера может оказаться неплохим выбором.

class MyCustomStream : Stream { Stream originalStream;

  MyCustomStream(Stream originalStream) 
  { this.originalStream = originalStream; }

  override int Read(byte [] buffer, int offset, int count) 
  {
      byte [] temp = new byte[count];
      var ret = originalStream.Read(temp, offset, count);
      // modify your buffer if desired
      Array.Copy(buffer, temp);
      return ret;
  }

  // implement all the other abstract methods of Stream and just call originalStream 

}

// теперь заменяем такой код....

var myStream = request.GetResponseStream();

// с....

var myStream = новый MyCustomStream(request.GetResponseStream());

person user2812885    schedule 24.09.2013
comment
Это, вероятно, не будет работать для моего случая. Это веб-служба Java, которую я использую через .net, и она отправляет немного контента, который на самом деле не работает на стороне клиента. Я уже создал подкласс из исходного прокси-сервера и переопределил метод GetWebResponse, и в этом методе мне действительно нужно изменить содержимое потока, чтобы при его фактическом анализе не возникало исключение. Надеюсь, вы поняли суть - person Bukhatir; 25.09.2013
comment
Не уверен, что знаю ... если вы измените его на уровне потока, это будет до того, как что-либо будет проанализировано, верно? - person user2812885; 25.09.2013
comment
да дело в этом. если я могу просто изменить его в тот момент, когда он будет работать. Последующий синтаксический анализ не подведет. - person Bukhatir; 25.09.2013
comment
Итак, если вы оберните поток, как я показал вам (при условии, что вы можете изменить код, вызывающий GetResponseStream), вы можете изменить содержимое буфера в точке комментария // изменить свой буфер, если хотите. Это изменит содержимое потока. с точки зрения вызывающего абонента, и у вас будет полный контроль над тем, что получает вызывающий абонент. - person user2812885; 25.09.2013
comment
В этом случае методом-оболочкой для метода GetResponseStream является метод GetWebResponse, который я могу переопределить, поэтому у меня есть доступ к коду, вызывающему метод GetResponseStream. Но проблема здесь в том, что возвращаемый здесь веб-ответ по-прежнему будет содержать исходный поток, и снова при десериализации/анализе это приведет к исключению. - person Bukhatir; 25.09.2013