2009-07-09 16 views
12

Quiero usar svcutil para mapear múltiples espacios de nombres wsdl al espacio de nombres clr al generar proxies de servicio. Uso versiones fuertes de espacios de nombres y, por lo tanto, los espacios de nombres clr generados son incómodos y pueden significar muchos cambios en el código del lado del cliente si cambia la versión del espacio de nombres wsdl/xsd. Un ejemplo de código sería mejor para mostrar lo que quiero.use svcutil para mapear múltiples espacios de nombres para generar proxies de servicio 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 - sin asignación de espacio de nombres

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 

El proxy generada parece

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

Las clases de cliente están fuera de cualquier espacio de nombres. Cualquier cambio en el espacio de nombres xsd implicaría cambiar todas las instrucciones de uso en mi código de cliente, toda compilación se romperá.

2. svcutil - con la asignación de espacio de nombres comodín

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 

El proxy generada parece

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

en cuenta que svcutil ha cambiado automáticamente una de las clases de direcciones para Address1. No me gusta esto Todas las clases de clientes también están dentro del mismo espacio de nombres.

Lo que quiero

Algo como esto:

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 esta manera puedo agrupar de forma lógica el espacio de nombres CLR y cualquier cambio de espacio de nombres WSDL/XSD se maneja en la generación de proxy única sin afectar el resto del código del lado del cliente.

Ahora esto no es posible. El svcutil permite mapear solo uno o todos los espacios de nombres, no una lista de mapeos.

que pueda hacer un mapeo como se muestra a continuación, pero no múltiples

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

Pero ¿hay alguna solución. Svcutil no es mágico, está escrito en .Net y genera programáticamente los proxies. ¿Alguien ha escrito un alterno a svcutil o me indica direcciones para que yo pueda escribir uno?

+0

¿Qué pasa si sólo utiliza "Agregar referencia de servicio"? –

+0

No lo he intentado ya que necesito usar el svcutil para generar proxy desde dll. Pero supongo que dado que la opción "agregar referencia de servicio" tiene la opción de ingresar solo un espacio de nombre, sería lo mismo que la asignación de espacio de nombres de comodines. – softveda

Respuesta

20

Puede hacer múltiples asignaciones de espacios de nombres proporcionando parámetros de espacio de nombres adicionales, no mediante el punto y coma de separación. Por lo que su ejemplo debería ser en cambio

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 

Aunque, actualmente estoy teniendo problemas en los tipos generados a partir de los archivos .xsd no se ven afectados por estos espacios de nombres. Solo los tipos generados a partir de los archivos .wsdl. La documentación implica que ambos deberían ser.

+2

¿Alguna suerte al hacer que la asignación del espacio de nombres también afecte a los tipos xsd? –

+0

@Lester: no lo perseguí mucho más en ese momento. Terminamos evitando la necesidad de xsds incorporando esos tipos en wsdls, creo. (Han pasado 3 años, claro). ¿Quizás VS2010 mejoró en esta situación? Lo anterior se hizo con VS2008. –

+1

@DaveCameron Pasan otro par de años, y todavía estoy abordando este mismo problema en VS2013 :-( –

0

Sólo en caso de que desee asignar todos los espacios de nombres de esquema en un espacio de nombres CLR a continuación:

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