我在一个有点棘手的开发上被困了几天。说明:
功能需求:公开具有不同绑定类型的唯一服务,这些绑定类型在运行时共享相同的约定AND开关,在客户端的功能中使用哪个绑定(是.Net客户端,使用Net.tcp-如果是Java客户端,则使用http绑定)。
以下是我的配置文件中的内容:
<!-- Test Service -->
<service name="TestService.v1.TestServiceImplementation, TestService" behaviorConfiguration="MyBehavior">
<endpoint name="TestServiceV1Htpp" contract="ITestService.v1" address="http://localhost:6001/TestService/v1" binding="basicHttpBinding" bindingConfiguration="HttpConf" behaviorConfiguration="HttpSOAPBehavior"/>
<endpoint name="TestServiceV1NetTcp" contract="ITestService.v1" address="net.tcp://localhost:6002/TestService/v1" binding="customBinding" bindingConfiguration="TcpConfStream" behaviorConfiguration="TcpSOAPBehavior"/>
</service>
测试服务数据合同:
[ServiceContract(...)]
public interface ITestService : IDisposable
{
[OperationContract]
IEnumerable<string> GetData();
}
[ServiceBehavior(...)]
public class TestServiceImplementation : ITestService
{
public IEnumerable<string> GetData()
{
yield return "Pong";
}
}
以及我的"运行时"合约的修改(在端点行为中,为了伪造一个stremed返回结果):
public sealed class CustomBehavior : IEndpointBehavior
{
void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
foreach (var msg in endpoint.Contract.Operations.First().Messages)
{
var part = msg.Body.ReturnValue;
if (part != null)
part.Type = typeof(Stream);
}
}
}
执行:
如果我不使用我的CustomBehavior,一切都会完美运行。当我将其添加到我的TCP端点(TcpSOAPBehavior)的行为配置中时,Body.ReturnValue.Type会被修改,并且此修改会更改ALL我的所有端点的合约。(甚至http…)。虽然我只想修改TCP端点合约,但不要碰http合约。。。有可能做出这样的修改吗?或者这些端点旨在永远共享同一个合同?
经过几天的工作,我找到了一个解决方案。我收到了以下错误信息:
InnerException消息为"Type"System.Collections.Generic.List"1[[System.String]]",不应使用数据协定名称"ArrayOfValuationResult_testService_wsdl"。将任何未知类型静态添加到已知类型列表中,例如,使用KnownTypeAttribute属性或将其添加到传递给DataContractSerializer的已知类型列表。
我在界面上使用了ServiceKnownTypeAttribute,如下博客所示:http://blogs.msdn.com/b/youssefm/archive/2009/04/21/understanding-known-types.aspx
通过这种方式,我可以公开一个IEnumerable,但在Stream中转换它,并使用TCP/Http绑定成功调用。