从asmx升级到wcf时,是否需要使用DataMember属性修饰每个成员?

时间:2011-06-17 19:50:18

标签: wcf asmx

我有一个目前正在使用asmx的网络服务。操作使用WebMethod进行修饰,每个操作都接受请求并返回响应。我开始创建一个WCF应用程序,我正在引用业务层,因此我可以重用Web方法。我的问题是,我是否必须使用DataContract来装饰每个类以及使用DataMember的请求的每个属性?

目前,其中一个类使用SerializableAttribute,XmlTypeAttribute和XmlRootAttribute进行修饰。我是否需要删除这些并添加DataContract,或者我可以向其添加DataContract吗?顺便说一句,它是一个.NET 2应用程序。该类还包含一堆私有字段和公共属性,我是否需要使用DataMember属性来装饰它们。如果它使用.NET 2框架,这甚至可能吗?

WCF服务目前面向.NET Framework 4.0。一些方法仍然需要使用XmlSerializer,这是否意味着我可以用[XmlSerializerFormat]装饰操作?

您能详细说明不在服务边界上使用任何业务对象吗?什么是DTO?

如果可能的话,你能举个例子吗?

2 个答案:

答案 0 :(得分:2)

从.NET 3.5 SP1开始,DataContractSerializer不需要使用属性(称为POCO支持)。虽然这使您无法控制生成的XML

但是,如果您已经拥有ASMX服务,那么为了保持相同的序列化,您真的想要使用XmlSerializer。您可以使用[XmlSerializerFormat]属性在WCF中连接它,该属性可以在服务合同或单个操作级别应用

编辑:在DTO上添加部分

但是,将业务对象置于服务边界会导致潜在问题:

  1. 您可能正在公开纯粹属于业务规则的不必要数据
  2. 您将服务使用者紧密地联系到您的业务层,从而导致代码中的脆弱性并阻止您自由重构
  3. 数据传输对象(DTO)的想法是创建类,其生命中唯一的角色是管理XML和对象世界之间的转换。这也符合Single Responsibility Principle。 DTO可以显示必要的数据,并充当业务变更和有线格式之间的缓冲区。这是一个例子

    [ServiceContract]
    interface ICustomer
    {
        [OperationContract]
        CustomerDTO GetCustomer(int id);
    }
    
    class CustomerService : ICustomer
    {
        ICustomerRepository repo;
        public CustomerService (ICustomerRepository repo)
        {
            this.repo = repo;
        }
    
        public CustomerService()
            :this(new DBCustomerRepository())
        {
    
        }
    
        public CustomerDTO GetCustomer(int id)
        {
            Customer c = repo.GetCustomer(id);
            return new CustomerDTO
            {
                Id = c.Id,
                Name = c.Name,
                AvailableBalance = c.Balance + c.CreditLimit,
            };
        }
    }
    
    class Customer
    {
        public int Id { get; private set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public decimal Balance { get; set; }
        public decimal CreditLimit { get; set; }      
    }
    
    [DataContract(Name="Customer")]
    class CustomerDTO
    {
        [DataMember]
        public int Id { get; private set; }
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public decimal AvailableBalance { get; set; }
    }
    

    使用DTO,您可以通过服务公开现有的业务功能,而无需出于纯技术原因对业务功能进行更改

    人们倾向于使用DTO解决的一个问题是必须在它们和业务对象之间进行映射。但是,当你考虑它们带来的好处时,我认为这是一个很小的代价,而AutoMapper

    等工具可以大大降低价格。

答案 1 :(得分:0)

WCF使用的DataContractSerializer主要基于以下属性:DataContract, DataMember, ServiceContract等等。但它也支持SerializableAttribute等。这个http://msdn.microsoft.com/en-us/library/ms731923.aspx文档为您提供了所需的全部见解。

因此,您可能不需要重构所有现有代码,但需要进一步调查和测试;)

相关问题