简体   繁体   中英

Sharing WSDL types without XSD

I can't seem to find an example of generating proxies from WSDLs with shared types but without having any XSDs to go along with them. Can anyone please mark this as duplicate and point me to an example please?

Here are 2 services, each has its own namespace and a common type. The only thing that is publicly accessible are their WSDLs, there is no type's XSD or its .dll to pass to wsdl.exe /sharedtypes or svcutils and without it I end up with identical class Foo that I can't pass in to SetFoo and class Foo1 .

The best I could come up with is generating proxies programmatically and detecting duplicates via CodeDOM, ignoring DataContract / WebServiceBinding namespaces, but it's a huge mess...

[WebService(Namespace = "http://tempuri.org/FOO1")]
public class Service1 : WebService
{
    [WebMethod]
    public Foo GetFoo()
    {
        return new Foo();
    }
}

[WebService(Namespace = "http://tempuri.org/FOO2")]
public class Service2 : WebService
{
    [WebMethod]
    public void SetFoo(Foo foo)
    {
    }
}

public class Foo
{
    public int Bar { get; set; }
}

There is a way of doing this, which is outlined here .

In your case you can skip the first step, generate the proxy from service 1 and then use the /r flag on svcutil to reference the service 1 proxy assembly when you generate your service 2 proxy.

This will ensure your service 2 proxy will use the same instance of Foo from your service 1 proxy.

However, have you considered just hosting a single service with two operations? It would save you a lot of work.

Edit: Also have a look at this post: http://blogs.msdn.com/b/youssefm/archive/2009/10/09/reusing-types-in-referenced-assemblies-with-svcutil-sr-switch.aspx

First off, you need to set the [DataContract(Namespace="some namespace here")] for all common service data types, otherwise when the WSDL and XSDs are generated then you will have objects from two difference namespace --- this is absolutely essential . The namespace value will only apply to the types defined in the XSD and not in the WSDL. XSD = data, WSDL = service.

The XSDs and WSDL and generated if, and only if, you have the META service behavior set - add this behavior and then you can navigate to the URL. The URL of the META service behavior will then have a link to your WSDLs and XSDs.

I use the following piece of code to self-host services in windows services rather than through IIS, however the same principals apply....

/// <summary>
/// Enables meta data output for a service host.
/// </summary>
/// <param name="host">The service host.</param>
/// <remarks>Must be invoked prior to starting the service host.</remarks>
public static void SetupMetaDataBehaviour(ServiceHost host)
{
    ServiceMetadataBehavior metaDataBehaviour = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
    if (metaDataBehaviour == null)
    {
        metaDataBehaviour = new ServiceMetadataBehavior();
        metaDataBehaviour.HttpGetEnabled = true;
        host.Description.Behaviors.Add(metaDataBehaviour);
    }
    else
    {
        metaDataBehaviour.HttpGetEnabled = true;
    }
}

after adding your two web references:

  1. double click on the second web service reference
  2. in the object browser navigate to the definition of Foo
  3. right click on Foo and choose go to definition
  4. delete the definition for the class Foo
  5. add a using statement for the namespace of webservice one
  6. find and replace all instances of <namespace-of-service-reference-2>.Foo with just Foo

This should fix your problem as it forces the autogenerated code for both service references to use the same class declaration.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM