这是一个应该返回“Hello World”字符串的简单示例。但是,浏览器会显示SGVsbG8gV29ybGQ=
之类的内容。从oldskul风格的服务返回纯文本的正确方法是什么?
请知道:
我无法返回字符串:将自动添加三个Unicode字符,旧版HTTP客户端将无法互操作。
我可以返回Message
,但仍然必须保留解析功能以提取data
变量。不允许在同一方法签名中混合使用Message
和int
类型的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"); } }
更新:这不是乱码,而是正确编码的响应。但是,格式不是我期望收到的。我已经想出(正如下面的绅士所说),使用Message
类可以获得对传输层消息传递格式的最终控制。但是,如果我使用一个 - 我放弃了解析请求(UriTemplate
属性)的可能性。因此,很高兴知道如何将Message
与UriRequest
进行整合。
P.S。如果无法实现“干净”整合 - 那么最优雅的解决方法是什么?请问在我的实施中我可以借用和使用的线幕背后是否有任何代码?
答案 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类。