2009-07-09 5 views
12

Chcę użyć svcutil do odwzorowania wielu przestrzeni nazw wsdl na przestrzeń nazw Clr podczas generowania proxy usługi. Używam silnej wersji przestrzeni nazw i dlatego wygenerowane przestrzenie nazw Clr są niezręczne i mogą oznaczać wiele zmian po stronie klienta, jeśli zmieni się wersja przestrzeni nazw wsdl/xsd. Przykład kodu lepiej będzie pokazać to, co chcę.użyj svcutil do mapowania wielu przestrzeni nazw do generowania proxy usług 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 - bez odwzorowania przestrzeni nazw

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 

Wygenerowany proxy wygląda

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

Klasy klienckie są z wszelkich nazw. Każda zmiana w przestrzeni nazw xsd oznaczałaby zmianę wszystkich instrukcji użycia w moim kodzie klienckim, cała kompilacja zostanie przerwana.

2. svcutil - z wieloznacznego mapowania przestrzeni nazw

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 

Wygenerowany proxy wygląda

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

Zauważ, że svcutil została automatycznie zmieniona jeden z klasy Adres do Address1. Nie podoba mi się to. Wszystkie klasy klientów znajdują się również w tej samej przestrzeni nazw.

Co chcę

coś takiego:

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 

ten sposób mogę logicznie grupa przestrzeń nazw CLR i jakakolwiek zmiana nazw wsdl/xsd jest obsługiwana w pokoleniu proxy tylko bez wpływu pozostały kod po stronie klienta.

Teraz nie jest to możliwe. Svcutil pozwala mapować tylko jedną lub wszystkie przestrzenie nazw, a nie listę mapowań.

mogę zrobić jedno mapowanie, jak pokazano poniżej, ale nie wielokrotność

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

Ale czy istnieje jakieś rozwiązanie. Svcutil nie jest magią, jest napisany w .Net i programowo generuje proxy. Czy ktoś napisał alternatywę do svcutilu lub wskazał mi drogę, abym mógł ją napisać.

+0

Co się stanie, jeśli po prostu użyć „Dodaj usługi Reference”? –

+0

Nie próbowałem, ponieważ muszę użyć svcutil do generowania proxy z biblioteki dll. Ale myślę, że biorąc pod uwagę, że "dodaj odniesienie do usługi" ma opcję wprowadzania tylko jednej przestrzeni nazw, to byłby taki sam jak mapowanie obszarów nazw wieloznacznych. – softveda

Odpowiedz

20

Można wykonać wiele mapowań przestrzeni nazw, zapewniając dodatkowe parametry przestrzeni nazw, a nie separując je średnikiem. Więc twój przykład powinien zamiast być

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 

Chociaż, jestem obecnie kłopoty gdy typy generowane z plików .XSD nie dotyczy tych nazw. Istnieją tylko typy wygenerowane z plików .wsdl. Dokumentacja sugeruje, że obie powinny być.

+2

Powodzenia w mapowaniu przestrzeni nazw również wpływają na typy XSD? –

+0

@Lester: Nie realizowałem tego zbyt długo. W końcu uniknęliśmy potrzeby używania xsdów poprzez osadzanie tych typów we wsdls, które myślę. (Minęły 3 lata, pamiętajcie.) Może VS2010 poprawił się w tej sytuacji? Powyższe zostało wykonane przy użyciu VS2008. –

+1

@DaveCameron Jeszcze kilka lat minęło, a ja wciąż trafiam na ten sam problem w VS2013 :-( –

0

Tylko w przypadku, gdy chcesz odwzorować wszystkie przestrzenie nazw schematu do jednego CLR nazw następnie:

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