使用webHttpBinding从服务获取Gibberish而不是Hello World

时间:2010-09-27 15:29:02

标签: .net wcf webhttpbinding operationcontract uritemplate

这是一个应该返回“Hello World”字符串的简单示例。但是,浏览器会显示SGVsbG8gV29ybGQ=之类的内容。从oldskul风格的服务返回纯文本的正确方法是什么?

请知道:

  1. 我无法返回字符串:将自动添加三个Unicode字符,旧版HTTP客户端将无法互操作。

  2. 我可以返回Message,但仍然必须保留解析功能以提取data变量。不允许在同一方法签名中混合使用Messageint类型的AFAIK。

    [ServiceContract(SessionMode=SessionMode.NotAllowed)] 
    public interface IHello 
    {
      [WebGet(UriTemplate = "manager?data={data}")]
      [OperationContract]
      Byte[] DoIt(int data);
    }

    public class Hello : IHello { public Byte[] DoIt(int data) { return Encoding.ASCII.GetBytes("HelloWorld"); } }

  3. 更新:这不是乱码,而是正确编码的响应。但是,格式不是我期望收到的。我已经想出(正如下面的绅士所说),使用Message类可以获得对传输层消息传递格式的最终​​控制。但是,如果我使用一个 - 我放弃了解析请求(UriTemplate属性)的可能性。因此,很高兴知道如何将MessageUriRequest进行整合。

    P.S。如果无法实现“干净”整合 - 那么最优雅的解决方法是什么?请问在我的实施中我可以借用和使用的线幕背后是否有任何代码?

3 个答案:

答案 0 :(得分:1)

这不是胡言乱语 - 它是“Hello World”(带空格)的ASCII字节的base64编码版本。

当您要求Web服务传输字节时,它将使用base64 ...您的Web服务客户端将自动执行base64解码,以使您返回原始字节。

(我不建议您使用Encoding.ASCII,请注意。)

目前还不清楚你的“遗留HTTP客户端”是什么,或者它的期望是什么,所以我们无法确定返回字节数组是否真的是最好的答案。

答案 1 :(得分:1)

用Google搜索一个正确的整合方式,发现人们就像我一样被卡住(如果我错了,请纠正我)。到目前为止,以下解决方法对我来说很好:

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

如果有更好的选择 - 了解它是完美的。

答案 2 :(得分:0)

SOAP规范声明原始二进制数据应该是base64编码的。所以你见证的行为是正确的。

如果需要传输ASCII字符数据。您可以使用一个消息合同和一个原始消息。

Message DoIt(DoItRequest request)

原始消息将创建包含ASCII数据的响应。 消息协定用于检索您提到的int参数:

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

这个page解释了如何使用Message类。