我遵循WSDL-first(由我们的客户提供)方法来开发WCF服务,但是从我的wcf服务生成的WSDL与我们的客户提供给我的WSDL略有不同,并且由于这种不匹配,客户端面临着难以制作致电我的服务。
客户提供了wsdl:
<wsdl:service name='CheckoutService'>
<wsdl:port binding='tns:CheckoutBinding' name='CheckoutServicePort'>
<soap:address location='place holder to service uri' />
</wsdl:port>
</wsdl:service>
从wcf服务生成的WSDL:
<wsdl:service name="CheckoutService">
<wsdl:port binding="tns:CheckoutBinding" name="CheckoutBinging">
<soap:address location="place holder to service uri" />
</wsdl:port>
</wsdl:service>
,我的服务设置如下:
<endpoint name="CheckoutBinding" address="" binding="basicHttpBinding" bindingName="CheckoutServicePort" bindingConfiguration="basicHttpBinding" bindingNamespace="<<namespace>>" contract="<<contractname>>" />
我已经使用WSCF.Blue从客户端提供的wsdl生成服务器存根代码,并在生成的代码中进行了微小的更改,以发出与客户端提供的WSDL完全相同的WSDL,但我不知道对于在配置文件或生成的代码中生成与客户端提供的wsdl文件中相同的“wsdl:port / @ name”。
根据此url,serviceendpoint name属性映射到wsdl:port / @ name和wsdl:binding / @ name。基于此,我的配置文件中的endpoint / @ name属性值映射到wsdl:port / @ name和wsdl:binding / @ name但我希望将不同的名称映射到wsdl:port / @ name和wsdl:binding / @name属性。
请帮助我实现这一目标。
答案 0 :(得分:18)
您可以尝试实现IWsdlExportExtension,并在ExportEndpoint中修改wsdl:port / @ name。然后实现IEndpointBehavior,它将您的扩展添加到端点。要使用新行为,您有两种选择:
以下是扩展元素的简单示例:
using System;
using System.Configuration;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
namespace CustomWsdlExtension
{
public class PortNameWsdlBehavior : IWsdlExportExtension, IEndpointBehavior
{
public string Name { get; set; }
public void ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)
{
}
public void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)
{
if (!string.IsNullOrEmpty(Name))
{
context.WsdlPort.Name = Name;
}
}
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
public class PortNameWsdlBehaviorExtension : BehaviorExtensionElement
{
[ConfigurationProperty("name")]
public string Name
{
get
{
object value = this["name"];
return value != null ? value.ToString() : string.Empty;
}
set { this["name"] = value; }
}
public override Type BehaviorType
{
get { return typeof(PortNameWsdlBehavior); }
}
protected override object CreateBehavior()
{
return new PortNameWsdlBehavior { Name = Name };
}
}
}
配置:
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="portName" type="CustomWsdlExtension.PortNameWsdlBehaviorExtension, CustomWsdlExtension" />
</behaviorExtensions>
</extensions>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="customPortName">
<portName name="myCustomName" />
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="CustomWsdlExtension.Service">
<endpoint address="" binding="basicHttpBinding" contract="CustomWsdlExtension.IService"
behaviorConfiguration="customPortName" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
我的WSDL看起来像:
<wsdl:service name="Service">
<wsdl:port name="myCustomName" binding="tns:BasicHttpBinding_IService">
<soap:address location="http://localhost:2366/Service.svc" />
</wsdl:port>
</wsdl:service>