2009-07-09 9 views
12

Je souhaite utiliser svcutil pour mapper plusieurs espaces de noms wsdl sur l'espace de noms clr lors de la génération de proxys de service. J'utilise un versionnement fort des espaces de noms et, par conséquent, les espaces de noms clr générés sont gênants et peuvent entraîner de nombreux changements de code côté client si la version de l'espace de noms wsdl/xsd change. Un exemple de code serait mieux de montrer ce que je veux.utiliser svcutil pour mapper plusieurs espaces de noms pour générer des proxies de service wcf

// 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 - sans mappage d'espace de noms

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 

Le proxy généré ressemble

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{} 
} 

Les classes client sont hors de tout namespaces. Toute modification de l'espace de noms xsd impliquerait la modification de toutes les instructions using dans mon code client, toutes les builds se casseront.

2. svcutil - avec la cartographie de l'espace de noms génériques

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 

Le proxy généré ressemble

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

Notez que svcutil a changé automatiquement l'un de la classe d'adresses pour Adresse1. Je n'aime pas ça. Toutes les classes client sont également dans le même espace de noms.

Ce que je veux

Quelque chose comme ceci:

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 

De cette façon, je peux regrouper logiquement l'espace de noms clr et toute modification de l'espace de noms wsdl/xsd est traitée dans la génération de proxy uniquement sans affecter le reste du code côté client.

Maintenant, ce n'est pas possible. Le svcutil permet de mapper seulement un ou tous les espaces de noms, pas une liste de mappages.

je peux faire une cartographie comme indiqué ci-dessous, mais pas plusieurs

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

Mais est-il une solution. Svcutil n'est pas magique, il est écrit en .Net et génère par programme les proxies. Est-ce que quelqu'un a écrit une alternative à svcutil ou me pointe vers les directions afin que je puisse en écrire un.

+0

Que se passe si vous utilisez juste « Ajouter un service de référence »? –

+0

Je n'ai pas essayé depuis que j'ai besoin d'utiliser svcutil pour générer un proxy depuis dll. Mais je suppose que, étant donné que "ajouter une référence de service" a l'option d'entrer un seul espace de noms, il serait le même que le mappage d'espaces de noms génériques. – softveda

Répondre

20

Vous pouvez effectuer plusieurs mappages d'espaces de noms en fournissant des paramètres d'espace de nom supplémentaires - et non en les séparant par des points-virgules. Donc, votre exemple devrait plutôt être

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 

Bien que, j'ai actuellement des problèmes où les types générés à partir de fichiers .xsd ne sont pas affectés par ces espaces de noms. Seuls les types générés à partir des fichiers .wsdl sont. La documentation implique que les deux devraient l'être.

+2

Avez-vous de la chance pour que le mappage d'espace de noms affecte également les types xsd? –

+0

@Lester: Je ne l'ai pas poursuivi beaucoup plus loin à ce moment-là. Nous avons fini par éviter le besoin de xsds en intégrant ces types dans le wsdls je pense. (Il a été 3 ans, attention à vous.) Peut-être VS2010 amélioré sur cette situation? Ce qui précède a été fait avec VS2008. –

+1

@DaveCameron Un autre couple d'années passe, et je suis toujours en train de frapper ce même problème dans VS2013 :-( –

0

Juste au cas où vous voulez mapper tous les schéma namespaces à un espace de noms CLR puis:

SvcUtil "your wsdl file.xml" /n:*,RequiredClrNamespace 
Questions connexes