类型“MyDTO”无法序列化 - Wcf 服务

Posted

技术标签:

【中文标题】类型“MyDTO”无法序列化 - Wcf 服务【英文标题】:Type 'MyDTO' cannot be serialized - Wcf Service 【发布时间】:2012-11-28 11:25:31 【问题描述】:

我正在创建 2 个 wcf 服务 - ADService 和 DBService。我正在使用称为 EmployeeDTO 和 CustomerDTO 的 DTO 在端点之间交换数据。 我无法将任何服务作为服务引用添加到我的解决方案中的其他项目,当我运行 WCF 主机并尝试访问 ADService.svc 或 DBService.svc 时,我得到以下信息:

无法序列化类型“DTOs.CustomerDTO”。考虑使用 DataContractAttribute 属性对其进行标记,并使用 DataMemberAttribute 属性标记您想要序列化的所有成员。如果类型是集合,请考虑使用 CollectionDataContractAttribute 对其进行标记。

无法序列化类型“DTOs.EmployeeDTO”。考虑使用 DataContractAttribute 属性对其进行标记,并使用 DataMemberAttribute 属性标记您想要序列化的所有成员。如果类型是集合,请考虑使用 CollectionDataContractAttribute 对其进行标记。

我的文件如下所示:

类 CustomerDTO

使用系统; 使用 System.Collections.Generic; 使用 System.Linq; 使用 System.Text; 命名空间 DTO 公共类 CustomerDTO 公共 int 客户 ID; 公共字符串名称; 公共字符串姓氏; 公共串街; 公共字符串 post_code; 公共字符串城市; 公共字符串国家; 公共字符串personal_code; 公共字符串电话号码; 公共字符串组类型; 公共字符串员工; 公共 CustomerDTO(int _customerID,字符串 _name,字符串 _surname,字符串 _street,字符串 _post_code,字符串 _city,字符串 _country,字符串 _personal_code,字符串 _phone_number,字符串 _group_type,字符串 _employee) this.customerID = _customerID; this.name = _name; this.surname = _surname; this.street = _street; this.post_code = _post_code; 这个.city = _city; this.country = _country; this.personal_code = _personal_code; this.phone_number = _phone_number; this.group_type = _group_type; this.employee = _employee;

类EmployeeDTO:

使用系统; 使用 System.Collections.Generic; 使用 System.Linq; 使用 System.Text; 命名空间 DTO 公共类EmployeeDTO 公共字符串给定名称; 公共字符串 sn; 公共字符串电话号码; 公共字符串 sAMAccountName; 公共字符串标题; 公串部; 公共字符串 distinctName; 公共字符串 OU; 公共布尔启用; 公共EmployeeDTO(字符串_givenName,字符串_sn,字符串_telephoneNumber,字符串_sAMAccountName,字符串_title,字符串_Department,字符串_distinguishedName,字符串_OU,布尔_启用) this.Department = _Department; this.distinguishedName = _distinguishedName; this.givenName = _givenName; this.sAMAccountName = _sAMAccountName; 这个.sn = _sn; this.telephoneNumber = _telephoneNumber; this.title = _title; 这个.OU = _OU; this.enable = _enable;

Web.config

<?xml version="1.0"?>
<configuration>
  <connectionStrings>
    <add name="ki_dbEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=WIN-D3T41W1E5EB\SQLEXPRESS;Initial Catalog=ki_db;Integrated Security=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient"/>
  </connectionStrings>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
    <services>
      <service name="WcfHost.ADService">
        <endpoint address="" binding="basicHttpBinding" contract="WcfHost.IADService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733/WcfServiceLibrary/ADService/" />
          </baseAddresses>
        </host>
      </service>
      <service name="WcfHost.DBService">
        <endpoint address="" binding="basicHttpBinding" contract="WcfHost.IDBService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733/WcfServiceLibrary/DBService/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>

IADService.cs

使用系统; 使用 System.Collections.Generic; 使用 System.Linq; 使用 System.Runtime.Serialization; 使用 System.ServiceModel; 使用 System.Text; 使用 System.Threading.Tasks; 使用 DTO; 使用 System.Security.Principal; 命名空间 WcfHost // 注意:您可以使用“重构”菜单上的“重命名”命令在代码和配置文件中同时更改接口名称“IADService”。 [服务合同] 公共接口IADService [运营合同] 布尔集连接(); . . . [运营合同] 任务 changeAccountStatus(EmployeeDTO _employee);

IDBService.cs 是类比定义的。

我似乎无法找到这个错误的原因,尤其是我的一个朋友有类似的实现并且它可以工作而我的没有。 任何帮助将不胜感激。

【问题讨论】:

您是否考虑过使用DataContractAttribute 属性标记它,并使用DataMemberAttribute 属性标记您想要序列化的所有成员? 【参考方案1】:

要通过网络序列化一个类,您需要使用 DataContract 和 DataMember 属性标记它(如它所说)。我相信您还需要将这些字段转换为属性。所以你需要:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DTOs

    [DataContract]
    public class CustomerDTO
    
        [DataMember]
        public int customerID  get; set; 

        [DataMember]
        public string name  get; set; 

        [DataMember]
        public string surname  get; set; 

        [DataMember]
        public string street  get; set; 

        [DataMember]
        public string post_code  get; set; 

        [DataMember]
        public string city  get; set; 

        [DataMember]
        public string country  get; set; 

        [DataMember]
        public string personal_code  get; set; 

        [DataMember]
        public string phone_number  get; set; 

        [DataMember]
        public string group_type  get; set; 

        [DataMember]
        public string employee  get; set; 

        public CustomerDTO(int _customerID, string _name, string _surname, string _street, string _post_code, string _city, string _country, string _personal_code, string _phone_number, string _group_type, string _employee)
        
            this.customerID = _customerID;
            this.name = _name;
            this.surname = _surname;
            this.street = _street;
            this.post_code = _post_code;
            this.city = _city;
            this.country = _country;
            this.personal_code = _personal_code;
            this.phone_number = _phone_number;
            this.group_type = _group_type;
            this.employee = _employee;
        
    

因为您的操作合同使用 EmployeeDTO 类型作为输入参数,这意味着客户端需要能够创建该类型并将其通过线路发送到服务器。所以一定要加上[DataContract]

【讨论】:

【参考方案2】:

正如错误消息中所说,将DataContract 属性放在类上方:

[DataContract]
public class CustomerDTO

...

您还需要将DataMember 属性放置在您希望通过服务提供的任何属性之上,并将OperationContract 放置在您希望提供的任何方法之上。

有关更多信息,请参阅本教程: http://www.wcftutorial.net/Data-Contract.aspx

【讨论】:

【参考方案3】:

我最近在尝试运行我的应用程序并在浏览器中显示 WSDL 时遇到此错误。这种情况很奇怪,因为黄色 WSDL 错误页面识别的对象实际上是我的 WCF 服务。这让我摸不着头脑。

结果我已经将 WCF 服务类添加到 ServiceKnownTypeAttribute,添加到一个错误的接口中,作为 [ServiceKnownType(typeof(classname))] 但是深夜......

因此,这是您收到此错误消息的另一个原因。

干杯

【讨论】:

以上是关于类型“MyDTO”无法序列化 - Wcf 服务的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 WCF 将派生类型序列化为其基类型

C# Restful WCF 服务。无法在帖子正文中反序列化 XML

WCF 无法反序列化 JSON 请求

WCF 奇怪的 ReadOnlyDictionary 序列化

序列化时未获取 xml 输入值以列出 wcf 服务中的类

在 C# 中为 WCF 服务反序列化简单的 XML 数组对象