我有一个WCF Web服务,我想要版本。在这种情况下,我有一个特定的操作MyOperation
,它可以更改类型签名并在语义上进行更改,以便获得新的主要版本。我希望客户端尽可能只将命名空间从 v1 更改为 v2 ,并能够使用新操作。
我使用严格的版本控制并定义服务合同(我使用占位符名称):
[DataContract(Namespace = "http://mycompany.com/myService/v1", Name = "MyOpResponse")]
public class MyOpResponse
{
[DataMember]
public string Value { get; set; }
}
[ServiceContract(Namespace = "http://mycompany.com/myService/v1")]
public interface IMyService
{
[OperationContract(Name = "MyOperation")]
MyOpResponse MyOperation(string parameter);
[OperationContract(Name = "MyOtherOperation")]
int MyOtherOperation(int parameter);
}
[DataContract(Namespace = "http://mycompany.com/myService/v2", Name = "MyOpResponse")]
public class MyOpResponse_v2
{
[DataMember]
public int Value { get; set; }
}
[ServiceContract(Namespace = "http://mycompany.com/myService/v2")]
public interface IMyService_v2
{
[OperationContract(Name = "MyOperation")]
MyOpResponse_v2 MyOperation_v2(string parameter);
[OperationContract(Name = "MyOtherOperation")]
int MyOtherOperation(int parameter);
}
我想将MyOperation
更改为具有新返回类型的新版本,但其他操作保持不变(例如MyOtherOperation
)
服务定义如下(使用默认实现):
public class MyService : IMyService, IMyService_v2
{
public MyOpResponse_v2 MyOperation_v2(string parameter)
{
return new MyOpResponse_v2 { Value = parameter.Length };
}
public int MyOtherOperation(int parameter)
{
return parameter + 100;
}
public MyOpResponse MyOperation(string parameter)
{
return new MyOpResponse { Value = parameter };
}
}
在我的 Web.config 中,我有以下定义:
<behaviors>
<endpointBehaviors>
<behavior name="MyEndpointBehavior" />
</endpointBehaviors>
</behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceSecurityAudit auditLogLocation="Application" suppressAuditFailure="true" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="Failure" />
<aspNetCompatibilityRequirementsBehavior requirementsMode="Allowed" />
</behavior>
</serviceBehaviors>
<bindings>
<basicHttpBinding>
<binding name="MyBinding">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<service behaviorConfiguration="MyServiceBehavior" name="MyCompany.MyService">
<endpoint address="" behaviorConfiguration="MyEndpointBehavior" binding="basicHttpBinding" bindingConfiguration="MyBinding" name="MyService" contract="MyCompany.IMyService" />
<endpoint address="" behaviorConfiguration="MyEndpointBehavior" binding="basicHttpBinding" bindingConfiguration="MyBinding" name="MyService_v2" contract="MyCompany.IMyService_v2" />
</service>
当我发布服务时,http://localhost/MyService.svc?wsdl中生成的WSDL似乎是正确的(我删除了不相关的名称空间和定义):
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:i1="http://mycompany.com/myService/v2" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://tempuri.org/" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:i0="http://mycompany.com/myService/v1" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" name="MyService" targetNamespace="http://mycompany.com/myService/v2">
<wsdl:binding name="MyService" type="i0:IMyService">
...
</wsdl:binding>
<wsdl:binding name="MyService_v2" type="i1:IMyService_v2">
...
</wsdl:binding>
<wsdl:service name="MyService">
<wsdl:port name="MyService" binding="tns:MyService">
<soap:address location="http://localhost/MyService.svc"/>
</wsdl:port>
<wsdl:port name="MyService_v2" binding="tns:MyService_v2">
<soap:address location="http://localhost/MyService.svc"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
但是,如果我尝试用http://localhost/MyService.svc?singleWsdl生成平面WSDL文件,我会收到此错误:
System.NotSupportedException: A single WSDL document could not be generated for this service. Multiple service contract namespaces were found (http://mycompany.com/myService/v1, http://mycompany.com/myService/v2). Ensure that all your service contracts have the same namespace.
通过上述解决方案,我在http://localhost/MyService.svc托管了我的两个服务版本。如果客户端想要调用v1,他只需要使用命名空间 http://mycompany.com/myService/v1 ;如果他想要更改为v2版本,他只需要将命名空间更改为http://mycompany.com/myService/v2。正确生成带导入的WSDL文件,但只生成错误的平面WSDL文件。我需要生成平面WSDL以提供给第三方。
是否可以使用上述版本控制系统并仍使用?singleWSDL正确生成平面WSDL?
如果没有,有什么更好的选择?