如何更改 WCf 服务的 wsdl 文件中的默认模式位置?

Posted

技术标签:

【中文标题】如何更改 WCf 服务的 wsdl 文件中的默认模式位置?【英文标题】:How to change the default schemalocation in wsdl file of WCf Service? 【发布时间】:2011-03-11 21:17:01 【问题描述】:

以下是我的服务的 wsdl 文件:

    <wsdl:types>
      <xsd:schema targetNamespace="http://tempuri.org/Imports">
      <xsd:import schemaLocation="http://localhost:3789/VideoUpload.svc?xsd=xsd0" namespace="http://tempuri.org/" /> 
      <xsd:import schemaLocation="http://localhost:3789/VideoUpload.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" /> 
      <xsd:import schemaLocation="http://localhost:3789/VideoUpload.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/UploadVideoProtocol" /> 
      </xsd:schema>
    </wsdl:types>
-----
<wsdl:definitions>
<wsdl:service name="VideoUpload">
<wsdl:port name="BasicHttpBinding_IVideoUpload" binding="tns:BasicHttpBinding_IVideoUpload">
  <soap:address location="http://localhost:3789/VideoUpload.svc" /> 
  </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

在上面,我可以通过在服务契约和行为的代码中指定自定义命名空间来更改命名空间。

但我需要更改架构位置中指定的端点地址,

schemaLocation="http://localhost:3789/VideoUpload.svc?xsd=xsd0"

到我自己定义的端点地址为:

schemaLocation="http://myservice.com:8080/VideoUpload.svc?xsd=xsd0"

实现这一目标的程序是什么?代码中必须提到什么来更改生成的默认端点?谁能帮我解决这个问题?

【问题讨论】:

您必须更改 httpGetUrl。看看这些帖子。 knowledgebaseworld.blogspot.com/2010/06/…knowledgebaseworld.blogspot.com/2010/06/… 嘿,谢谢...效果很好。但是当我分配一个域名而不是我无法访问的 IP 地址时。如何使用相同的域名而不是指定 IP 地址? 它应该可以工作,因为 dns 解析 IP 地址并将请求发送到特定 IP,请确保配置设置 web config 或 IIS 的配置设置?我已将 IIS 上托管的特定服务的主机标头更改为某个域 (www.yourdomain.com)。我在 httpGetUrl 中提到了与 http:\\www.yourdomain.com:8080/VideoUpload.svc? 相同的内容。但它不起作用。我可以知道在 IIS 中必须更改的所有设置是什么吗?你能帮我解决这个问题吗? 【参考方案1】:

您可以通过添加实现“IWsdlExportExtension”的新行为来动态更新 WSDL 元数据中的 WCF 端点地址

public class HostNameAddressBehavior : Attribute, IWsdlExportExtension, IEndpointBehavior, IServiceBehavior

    public void AddBindingParameters(ServiceEndpoint endpoint,
        BindingParameterCollection bindingParameters)
    
    

    public void ApplyClientBehavior(ServiceEndpoint endpoint,
        ClientRuntime clientRuntime)
    
    

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint,
        EndpointDispatcher endpointDispatcher)
    

    

    public void Validate(ServiceEndpoint endpoint)
    
    

    public void AddBindingParameters(ServiceDescription serviceDescription,
        ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints,
        BindingParameterCollection bindingParameters)
    
    

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription,
        ServiceHostBase serviceHostBase)
    
    

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    
    

    public void ExportContract(WsdlExporter exporter,
        WsdlContractConversionContext context)
    
    

    /// <summary>
    /// Overwrite service meta data
    /// </summary>
    /// <param name="exporter"></param>
    /// <param name="context"></param>
    public void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)
    
        var address = "YOUR_ENDPOINT";

        context.Endpoint.Address = new System.ServiceModel.EndpointAddress(address);

        XmlSchemaSet schemaSet = exporter.GeneratedXmlSchemas;

        foreach (System.Web.Services.Description.ServiceDescription wsdl in exporter.GeneratedWsdlDocuments)
        
            foreach (XmlSchema schema in wsdl.Types.Schemas)
            
                ChangeSchemaLocation(schemaSet, schema, address);
            
        
    

    /// <summary>
    /// Update XSD location
    /// </summary>
    /// <param name="xmlSchemaSet"></param>
    /// <param name="xsdDoc"></param>
    /// <param name="address"></param>
    private void ChangeSchemaLocation(XmlSchemaSet xmlSchemaSet, XmlSchema xsdDoc, string address)
    
        foreach (XmlSchemaExternal external in xsdDoc.Includes)
        
            if ((external != null) && string.IsNullOrEmpty(external.SchemaLocation))
            
                string str = (external is XmlSchemaImport) ? ((XmlSchemaImport)external).Namespace : xsdDoc.TargetNamespace;
                foreach (XmlSchema schema in xmlSchemaSet.Schemas(str ?? string.Empty))
                
                    if (schema != xsdDoc)
                    
                        external.SchemaLocation = address + "/?xsd=xsd0"; // set the location;
                        break;
                    
                
                continue;
            
        
    

通过代码或在配置文件中添加您的新行为。

按代码:

var endpoint = listener.ServiceHost.Description.Endpoints.First();
endpoint.Behaviors.Add(new HostNameAddressBehavior());

按配置:

创建扩展:

    public class HostNameAddressBehaviorExtension : BehaviorExtensionElement

    public override Type BehaviorType
    
        get
        
            return typeof(HostNameAddressBehavior);
        
    

    protected override object CreateBehavior()
    
        return new HostNameAddressBehavior();
    

然后添加:

<extensions>
    <behaviorExtensions>
      <add name="hostNameAddress" type="YourService.HostNameAddressBehaviorExtension, YourService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
    </behaviorExtensions>
  </extensions>

【讨论】:

以上是关于如何更改 WCf 服务的 wsdl 文件中的默认模式位置?的主要内容,如果未能解决你的问题,请参考以下文章

如何从现有的 WSDL 和 XSD 文件生成 WCF 服务主机

如何使用 WSDL 文件创建 WCF 代理?

如何从C#中的URL读取WCF服务的WSDL

wcf服务元数据WSDL中的地址为请求方地址不再是主机名

下载 WCF 服务公开的所有 WSDL 文件的最佳方法是啥?

下载 WCF 服务公开的所有 WSDL 文件的最佳方法是啥?