使用 webHttpBinding 从服务中获取乱码而不是 Hello World

发布于 2024-09-25 06:19:41 字数 1011 浏览 1 评论 0原文

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

请注意:

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

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

    [ServiceContract(SessionMode=SessionMode.NotAllowed)] 
    公共接口IHello 
    {
      [WebGet(UriTemplate = "经理?data={data}")]
      【运营合同】
      Byte[] DoIt(int 数据);
    }

    公共类Hello:IHello { 公共字节[] DoIt(int数据) { 返回 Encoding.ASCII.GetBytes("HelloWorld"); } }

更新:这不是乱码,而是正确编码的响应。但是,该格式不是我期望收到的格式。我已经发现(正如下面的先生们所建议的),传输层消息传递格式的最终​​控制是通过 Message 类获得的。但是,如果我确实使用了一个 - 我就失去了解析请求的可能性(UriTemplate 属性)。因此,如果知道如何将 MessageUriRequest 集成,那就太好了。

PS 如果“干净”的集成是不可能的 - 那么最优雅的解决方法是什么?请问是否有任何在幕后完成的代码可供我借用并在我的实现中使用?

Here is a trivial example that is supposed to return "Hello World" string. However, a browser displays something like SGVsbG8gV29ybGQ=. Which is the right way to return plain text from an oldskul-style service?

please know that:

  1. I can't return a string: three Unicode characters will be automatically prepended and the legacy HTTP client won't be able to interoperate.

  2. I could return a Message, but still must keep parsing functionality to extract the data variable. Mixing Message and int types in the same method signature is not allowed 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"); } }

UPDATE: It's not gibberish, but correctly encoded response. However, the format is not what I'd expect to receive. I've figured out (as gentlemen below suggest) that the ultimate control of the transport layer messaging format is gained with Message class. However, if I do use one - I loose the possibility of parsing the request (UriTemplate attribute). Hence, it would be great to know how to integrate the Message with UriRequest.

P.S. If the "clean" integration is not possible - than what's the most elegant workaround? Is there any code that is done behind the wire curtain that I can borrow and use in my implementation, please?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦中楼上月下 2024-10-02 06:19:41

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

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

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

不清楚您的“旧版 HTTP 客户端”是什么,或者它期望什么,因此我们无法真正判断是否返回一个字节数组实际上是否是最好的答案。

That's not gibberish - it's the base64-encoded version of the ASCII bytes for "Hello World" (with a space).

When you ask a web service to transmit bytes, it will use base64... your web service client will perform the base64 decoding automatically, to get you back the original bytes.

(I wouldn't suggest using Encoding.ASCII, mind you.)

It's not clear what your "legacy HTTP client" is, or what it's expecting, so we can't really tell whether returning a byte array is actually the best answer or not.

心奴独伤 2024-10-02 06:19:41

在谷歌上搜索了正确的集成方法,发现人们和我一样陷入困境(如果我错了,请纠正我)。到目前为止,以下解决方法对我来说效果很好:

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

如果有更好的替代方案 - 最好了解它。

Googled for a proper way to integrate and found that people are stuck just as I am (please correct me if I am wrong on that). So far the following workaround works fine for me:

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

If there is a better alternative - it would be perfect to know about it.

萌酱 2024-10-02 06:19:41

SOAP 规范规定原始二进制数据应采用 base64 编码。所以你所目睹的行为是正确的。

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

Message DoIt(DoItRequest request)

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

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

页面解释如何使用 Message 类。

The SOAP specification states that raw binary data should be base64 encoded. So the behavior you witness is correct.

If you need to transmit ASCII character data. You can use one message contract and a raw Message.

Message DoIt(DoItRequest request)

The raw message will create the response containing ASCII data.
The message contract is used to retrieve the int parameter you mentioned:

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

This page explains how to work with the Message class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文