2009-07-09 5 views
12

Ich möchte SVCUTIL verwenden, um beim Generieren von Dienstproxys mehrere WSDL-Namespaces dem CLR-Namespace zuzuordnen. Ich verwende eine starke Versionierung von Namespaces und daher sind die generierten clr-Namespaces peinlich und können viele clientseitige Codeänderungen bedeuten, wenn sich die wsdl/xsd-Namespaceversion ändert. Ein Codebeispiel wäre besser zu zeigen, was ich will.Verwenden Sie SVCutil, um mehrere Namespaces zum Generieren von WCF-Dienstproxys zuzuordnen

// Service code 
namespace TestService.StoreService 
{ 
    [DataContract(Namespace = "http://mydomain.com/xsd/Model/Store/2009/07/01")] 
    public class Address 
    { 
     [DataMember(IsRequired = true, Order = 0)] 
     public string street { get; set; } 
    } 

    [ServiceContract(Namespace = "http://mydomain.com/wsdl/StoreService-v1.0")] 
    public interface IStoreService 
    { 
     [OperationContract] 
     List<Customer> GetAllCustomersForStore(int storeId); 

     [OperationContract] 
     Address GetStoreAddress(int storeId); 
    } 

    public class StoreService : IStoreService 
    { 
     public List<Customer> GetAllCustomersForStore(int storeId) 
     { 
      throw new NotImplementedException(); 
     } 

     public Address GetStoreAddress(int storeId) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
} 

namespace TestService.CustomerService 
{ 
    [DataContract(Namespace = "http://mydomain.com/xsd/Model/Customer/2009/07/01")] 
    public class Address 
    { 
     [DataMember(IsRequired = true, Order = 0)] 
     public string city { get; set; } 
    } 

    [ServiceContract(Namespace = "http://mydomain.com/wsdl/CustomerService-v1.0")] 
    public interface ICustomerService 
    { 
     [OperationContract] 
     Customer GetCustomer(int customerId); 

     [OperationContract] 
     Address GetStoreAddress(int customerId); 
    } 

    public class CustomerService : ICustomerService 
    { 
     public Customer GetCustomer(int customerId) 
     { 
      throw new NotImplementedException(); 
     } 

     public Address GetStoreAddress(int customerId) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
} 

namespace TestService.Shared 
{ 
    [DataContract(Namespace = "http://mydomain.com/xsd/Model/Shared/2009/07/01")] 
    public class Customer 
    { 
     [DataMember(IsRequired = true, Order = 0)] 
     public int CustomerId { get; set; } 
     [DataMember(IsRequired = true, Order = 1)] 
     public string FirstName { get; set; } 
    } 
} 

1. svcutil - ohne Namespace-Mapping

svcutil.exe /t:metadata 
    TestSvcUtil\bin\debug\TestService.CustomerService.dll  
    TestSvcUtil\bin\debug\TestService.StoreService.dll 

svcutil.exe /t:code *.wsdl *.xsd /o:TestClient\WebServiceProxy.cs 

Der generierte Proxy sieht aus wie

namespace mydomain.com.xsd.Model.Shared._2009._07._011 
{ 
    public partial class Customer{} 
} 
namespace mydomain.com.xsd.Model.Customer._2009._07._011 
{ 
    public partial class Address{} 
} 
namespace mydomain.com.xsd.Model.Store._2009._07._011 
{ 
    public partial class Address{} 
} 

Die Client-Klassen aus allen Namensräumen sind. Jede Änderung am xsd-Namespace würde bedeuten, alle using-Anweisungen in meinem Client-Code zu ändern.

2. svcutil - mit Wildcard-Namespace-Mapping

svcutil.exe /t:metadata 
    TestSvcUtil\bin\debug\TestService.CustomerService.dll 
    TestSvcUtil\bin\debug\TestService.StoreService.dll 

svcutil.exe /t:code *.wsdl *.xsd /n:*,MyDomain.ServiceProxy 
    /o:TestClient\WebServicesProxy2.cs 

Der generierte Proxy sieht aus wie

namespace MyDomain.ServiceProxy 
{ 
    public partial class Customer{} 
    public partial class Address{} 
    public partial class Address1{} 
    public partial class CustomerServiceClient{} 
    public partial class StoreServiceClient{} 
} 

Beachten Sie, dass svcutil eine der Adressklasse Address1 automatisch geändert hat. Ich mag das nicht. Alle Clientklassen befinden sich ebenfalls in demselben Namespace.

Was ich

So etwas wollen:

svcutil.exe 
    /t:code *.wsdl *.xsd 
    /n:"http://mydomain.com/xsd/Model/Shared/2009/07/01, MyDomain.Model.Shared;http://mydomain.com/xsd/Model/Customer/2009/07/01, MyDomain.Model.Customer;http://mydomain.com/wsdl/CustomerService-v1.0, MyDomain.CustomerServiceProxy;http://mydomain.com/xsd/Model/Store/2009/07/01, MyDomain.Model.Store;http://mydomain.com/wsdl/StoreService-v1.0, MyDomain.StoreServiceProxy" 
    /o:TestClient\WebServiceProxy3.cs 

Auf diese Weise kann ich logisch Gruppe der CLR-Namespace und jede Änderung wsdl/XSD-Namespace in der Proxy-Generierung gehandhabt wird nur ohne Beeinträchtigung der Rest des clientseitigen Codes.

Jetzt ist das nicht möglich. Das SVCUTIL erlaubt es, nur einen oder alle Namespaces abzubilden, nicht eine Liste von Mappings.

Ich kann eine Zuordnung tun, wie unten, aber nicht mehrfach gezeigt

svcutil.exe 
    /t:code *.wsdl *.xsd 
    /n:"http://mydomain.com/xsd/Model/Store/2009/07/01, MyDomain.Model.Address" 
    /o:TestClient\WebServiceProxy4.cs 

Aber gibt es eine Lösung. Svcutil ist keine Magie, es ist in .Net geschrieben und generiert die Proxies programmatisch. Hat irgendjemand eine Alternative zu SVCutil geschrieben oder auf Anweisungen hingewiesen, damit ich eine schreiben kann?

+0

Was passiert, wenn Sie nur verwenden „Add Service Reference“? –

+0

Ich habe nicht versucht, da ich die SVCUTIL verwenden muss, um Proxy von DLL zu generieren. Aber ich denke, dass "add service reference" die Option hat, nur einen Namespace einzugeben, wäre es dasselbe wie Platzhalter-Namespace-Mapping. – softveda

Antwort

20

Sie können mehrere Namespace-Zuordnungen durchführen, indem Sie zusätzliche Namespace-Parameter angeben - nicht durch Semikolontrennung. So sollte Ihr Beispiel statt

svcutil.exe /t:code *.wsdl *.xsd 
/n:http://mydomain.com/xsd/Model/Shared/2009/07/01,MyDomain.Model.Shared 
/n:http://mydomain.com/xsd/Model/Customer/2009/07/01,MyDomain.Model.Customer 
/n:http://mydomain.com/wsdl/CustomerService-v1.0,MyDomain.CustomerServiceProxy 
/n:http://mydomain.com/xsd/Model/Store/2009/07/01,MyDomain.Model.Store 
/n:http://mydomain.com/wsdl/StoreService-v1.0,MyDomain.StoreServiceProxy 
/o:TestClient\WebServiceProxy3.cs 

sein Obwohl ich derzeit Probleme, bin wo die generierten Typen von XSD-Dateien werden von diesen Namensräumen betroffen. Nur die Typen, die aus den .wsdl-Dateien generiert werden, sind. Die Dokumentation impliziert, dass beides sein sollte.

+2

Haben Sie Glück, dass das Namespace-Mapping auch die xsd-Typen beeinflusst? –

+0

@Lester: Ich habe es damals nicht viel weiter verfolgt. Wir haben am Ende die Notwendigkeit für xsds vermieden, indem wir diese Typen in die WSDLs eingebettet haben, denke ich. (Es war 3 Jahre, wohlgemerkt.) Vielleicht verbessert VS2010 auf diese Situation? Das obige wurde mit VS2008 gemacht. –

+1

@DaveCameron Noch ein paar Jahre vergehen, und ich trete immer noch das gleiche Problem in VS2013 :-( –

0

Gerade falls Sie alle Schemanamespaces ein CLR-Namespace zur Karte dann:

SvcUtil "your wsdl file.xml" /n:*,RequiredClrNamespace 
Verwandte Themen