Получение Gibberish вместо Hello World из сервиса с webHttpBinding - PullRequest
0 голосов
/ 27 сентября 2010

Вот тривиальный пример, который должен возвращать строку «Hello World».Тем не менее, браузер отображает что-то вроде SGVsbG8gV29ybGQ=.Какой верный способ вернуть простой текст из сервиса в старом стиле?

пожалуйста, знайте, что:

  1. Я не могу вернуть строку: три символа Юникода будутавтоматически добавляется, и унаследованный HTTP-клиент не сможет взаимодействовать.

  2. Я мог бы вернуть Message, но все равно должен продолжать анализировать, чтобы извлечь переменную data.Смешивание типов Message и int в одной и той же сигнатуре метода не допускается AFAIK.<pre> [ServiceContract(SessionMode=SessionMode.NotAllowed)] public interface IHello { [WebGet(UriTemplate = "manager?data={data}")] [OperationContract] Byte[] DoIt(int data); }</p> <p>public class Hello : IHello { public Byte[] DoIt(int data) { return Encoding.ASCII.GetBytes("HelloWorld"); } }

ОБНОВЛЕНИЕ : Это не бред, а правильно закодированный ответ.Тем не менее, формат не то, что я ожидал бы получить.Я выяснил (как предполагают джентльмены ниже), что полный контроль над форматом сообщений транспортного уровня достигается с помощью класса Message.Однако, если я использую один - я теряю возможность парсинга запроса (атрибут UriTemplate).Следовательно, было бы здорово узнать, как интегрировать Message с UriRequest.

PS Если «чистая» интеграция невозможна - чем является самый элегантный обходной путь?Есть ли какой-нибудь код, который делается за проводной завесой, который я могу позаимствовать и использовать в своей реализации,

Ответы [ 3 ]

1 голос
/ 28 сентября 2010

Погуглил для правильного способа интеграции и обнаружил, что люди застряли так же, как и я (пожалуйста, поправьте меня, если я ошибаюсь в этом). До сих пор у меня отлично работает следующий обходной путь:

  public class Hello : IHello
  {
        [WebGet(UriTemplate = "manager")]
        [OperationContract]
        Message DoIt();
  }

  public class Hello : IHello
  {
        public Message DoIt()
        {
          var webContext = WebOperationContext.Current;
          var request = webContext.IncomingRequest;
          var queryParameters = request.UriTemplateMatch.QueryParameters;
          var data = queryParameters["data"];

          var result = new StringBuilder(@"
              <?xml version='1.0'?>
              ...
          ");

          var response = webContext.CreateTextResponse(result.ToString(), "application/xml", Encoding.ASCII);

          return response;
        }
  }

Если есть лучшая альтернатива - было бы прекрасно узнать об этом.

1 голос
/ 27 сентября 2010

Это не тарабарщина - это кодированная в base64 версия байтов ASCII для "Hello World" (с пробелом).

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

(я бы не советовал использовать Encoding.ASCII, заметьте.)

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

0 голосов
/ 28 сентября 2010

В спецификации SOAP указано, что необработанные двоичные данные должны быть в кодировке base64. Таким образом, поведение, свидетелем которого вы являетесь, является правильным.

Если вам нужно передать символьные данные ASCII. Вы можете использовать один контракт сообщения и необработанное сообщение.

Message DoIt(DoItRequest request)

Исходное сообщение создаст ответ, содержащий данные ASCII. Контракт сообщения используется для получения упомянутого вами параметра int:

[MessageContract]
public class DoItRequest
{
  [MessageBodyMember] public int data;
}

Эта страница объясняет, как работать с классом Message.

...