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

sof*_*eda 13 wcf svcutil.exe

我想在生成服务代理时使用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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

生成的代理看起来像

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{}
}
Run Code Online (Sandbox Code Playgroud)

客户端类不在任何名称空间中.对xsd命名空间的任何更改都意味着更改我的客户端代码中的所有using语句,所有构建都将中断.

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
Run Code Online (Sandbox Code Playgroud)

生成的代理看起来像

namespace MyDomain.ServiceProxy
{
    public partial class Customer{}
    public partial class Address{}
    public partial class Address1{}
    public partial class CustomerServiceClient{}
    public partial class StoreServiceClient{}
}
Run Code Online (Sandbox Code Playgroud)

请注意,svcutil已自动将Address类之一更改为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
Run Code Online (Sandbox Code Playgroud)

这样我就可以在逻辑上对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
Run Code Online (Sandbox Code Playgroud)

但有没有解决方案.Svcutil不是魔术,它是用.Net编写的,并以编程方式生成代理.有没有人写过svcutil的替代品或指向我的方向,以便我可以写一个.

Dav*_*ron 21

您可以通过提供额外的命名空间参数来执行多个命名空间映射 - 而不是通过分号分隔它们.所以你的例子应该是

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
Run Code Online (Sandbox Code Playgroud)

虽然,我目前遇到的问题是.xsd文件生成的类型不受这些命名空间的影响.只有.wsdl文件生成的类型.文档暗示两者都应该是.

  • 如果运气得到命名空间映射也会影响xsd类型呢? (2认同)

Hak*_*tık 5

以防万一您想要将所有架构命名空间映射到一个 CLR 命名空间,然后:

SvcUtil "your wsdl file.xml" /n:*,RequiredClrNamespace
Run Code Online (Sandbox Code Playgroud)