代码之家  ›  专栏  ›  技术社区  ›  softveda

使用svcutil映射多个命名空间以生成WCF服务代理

  •  12
  • softveda  · 技术社区  · 16 年前

    我希望在生成服务代理时使用svcutil将多个WSDL命名空间映射到clr命名空间。我使用名称空间的强版本控制,因此生成的clr名称空间比较麻烦,如果WSDL/XSD名称空间版本发生更改,可能意味着许多客户端代码会发生更改。代码示例最好能显示我想要的东西。

    // 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-不带命名空间映射

    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
    

    生成的代理看起来像

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

    客户端类不在任何命名空间中。对xsd名称空间的任何更改都意味着更改客户机代码中的所有using语句all build都将中断。

    2。svcutil-带有通配符命名空间映射

    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
    

    生成的代理看起来像

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

    请注意,svcutil已自动将其中一个地址类更改为address1。我不喜欢这个。所有客户端类也在同一个命名空间中。

    我想要什么

    像这样:

    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
    

    通过这种方式,我可以对clr名称空间进行逻辑分组,并且对wsdl/xsd名称空间的任何更改只在代理生成中处理,而不会影响客户端代码的其余部分。

    现在这是不可能的。svcutil只允许映射一个或所有名称空间,而不允许映射列表。

    我可以进行如下所示的一个映射,但不能进行多次映射

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

    但是有什么解决办法吗?svcutil不是魔法,它是用.NET编写的,并通过编程生成代理。是否有人给svcutil写了一个备选方案,或者给我指明方向,这样我就可以写一个。

    2 回复  |  直到 7 年前
        1
  •  20
  •   Dave Cameron    15 年前

    您可以通过提供额外的名称空间参数来执行多个名称空间映射,而不是通过分号分隔这些参数。所以你的例子应该是

    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
    

    尽管如此,我目前在从.xsd文件生成的类型不受这些名称空间影响的地方遇到了问题。只有从.wsdl文件生成的类型是。文件暗示两者都应该是。

        2
  •  1
  •   Hakan Fıstık MuriloKunze    7 年前

    为了避免将所有架构命名空间映射到一个CLR命名空间,请执行以下操作:

    SvcUtil "your wsdl file.xml" /n:*,RequiredClrNamespace
    
    推荐文章