如何在WCF服务的wsdl文件中更改默认的schemalocation?

11

以下是我的服务的 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://myservice.com:8080/VideoUpload.svc?xsd=xsd0"
如何实现这个过程?在代码中要提到什么来更改生成的默认终结点?请问有人可以帮帮我吗?

你需要更改httpGetUrl。查看这些帖子。 http://knowledgebaseworld.blogspot.com/2010/06/domain-name-replaced-with-machine-name.html http://knowledgebaseworld.blogspot.com/2010/06/wsdl-service-soap-address-location.html - IBhadelia
嘿,谢谢...非常好用。但是当我指定一个域名而不是IP地址时,我无法访问。如何使用域名而不是指定IP地址? - Googler
它应该能够工作,因为DNS解析IP地址并向特定IP发送请求,请确保配置设置正确。 - IBhadelia
Web Config或IIS的配置设置?我已经更改了托管在IIS上的特定服务的主机标头,例如某个域名(www.yourdomain.com)。我已在httpGetUrl中提到了相同的内容,如http:\\ www.yourdomain.com:8080 / VideoUpload.svc?但它不起作用。请问我需要更改哪些IIS设置?您能帮助我吗? - Googler
1个回答

0

您可以通过添加实现"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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接