【问题标题】:WCF service Exception:The formatter threw an exception while trying to deserialize the messageWCF 服务异常:格式化程序在尝试反序列化消息时引发异常
【发布时间】:2014-10-22 06:57:49
【问题描述】:

格式化程序在尝试反序列化消息时抛出异常:

尝试反序列化参数时出错 http://tempuri.org/:GetPatientInsuranceInformationResult。这 InnerException 消息是“第 1 行位置 1604 中的错误。元素 'http://schemas.datacontract.org/2004/07/SubSonic:_currentValue' 包含的数据 'http://schemas.datacontract.org/2004/07/System:DBNull' 数据合约。 反序列化器不知道映射到此的任何类型 合同。将 'DBNull' 对应的类型添加到已知列表中 类型 - 例如,通过使用 KnownTypeAttribute 属性或通过 将其添加到传递给的已知类型列表中 DataContractSerializer.'。请参阅 InnerException 了解更多详情

我的 wcf 服务函数

public PatientInsurance GetPatientInsuranceInformation(int PatientKey)
        {
            PatientInsurance col = new PatientInsurance();
            if (PatientKey > 0)
            {
                Query qry = new Query(PatientInsurance.Schema.TableName).WHERE(PatientInsurance.Columns.Deleted, false).AND(PatientInsurance.Columns.PatientKey, PatientKey);
                col.LoadAndCloseReader(qry.ExecuteReader());
            }
            return col;
        }

类总是由 subsonic 生成。我在业务逻辑中编写了部分类,如下所示

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;


namespace PatientPortal.Model.Data
{
    [KnownType(typeof(System.DBNull))]
    [XmlInclude(typeof(DBNull))]
    [KnownType(typeof(PatientInsurance))]
    public partial class PatientInsurance
    {
        public string InsuranceTypeText
        {
            get
            {
                string insuranceTypeText = "";
                //if (!string.IsNullOrEmpty(Convert.ToString(this.InsuranceType)))
                //{
                //    int InsuranceType = Convert.ToInt32(this.InsuranceType);
                //    switch (InsuranceType)
                //    {
                //        case 1:
                //            insuranceTypeText = "Primary Insurance";
                //            break;
                //        case 2:
                //            insuranceTypeText = "Secondary Insurance";
                //            break;
                //        case 3:
                //            insuranceTypeText = "Tertiary Insurance";
                //            break;
                //    }
                //}
                return insuranceTypeText;
            }
        }

        public string PrimPolicyHolderNameDisplay
        {
            get
            {
                string primPolicyHolderNameDisplay = "display:none;";
                if (!string.IsNullOrEmpty(Convert.ToString(this.PrimRelationship)))
                {
                    primPolicyHolderNameDisplay = (this.PrimRelationship == "Self") ? "display:none;" : "";
                }
                return primPolicyHolderNameDisplay;
            }
        }

        public string SecPolicyHolderNameDisplay
        {
            get
            {
                string secPolicyHolderNameDisplay = "display:none;";
                if (!string.IsNullOrEmpty(Convert.ToString(this.SecRelationship)))
                {
                    secPolicyHolderNameDisplay = (this.SecRelationship == "Self") ? "display:none;" : "";
                }
                return secPolicyHolderNameDisplay;
            }
        }

        public string TerPolicyHolderNameDisplay
        {
            get
            {
                string terPolicyHolderNameDisplay = "display:none;";
                if (!string.IsNullOrEmpty(Convert.ToString(this.TerRelationship)))
                {
                    terPolicyHolderNameDisplay = (this.TerRelationship == "Self") ? "display:none;" : "";
                }
                return terPolicyHolderNameDisplay;
            }
        }
    }
}

.

【问题讨论】:

  • 解决此问题所需的所有信息都在异常消息中...您到底需要我们提供什么?
  • 您能否发布您的网络服务接收的课程以及网络服务本身?
  • 你好 Nate Kerkhofs!谢谢你的回复..:) 我已经更新了我的问题

标签: c# wcf subsonic


【解决方案1】:

我的 WCF 服务是使用框架 4.5 构建的,而我的消费客户端是使用框架 3.5 构建的。由于这个添加服务引用向导没有为使用声明的 KnownTypes 生成 Class 属性

 [ServiceKnownType(typeof(System.DBNull))] 

所以,当反序列化客户端时没有得到 System.DBNull 类型。我们必须在客户端配置文件中添加 knowntypes。

客户端需要的这个配置解决了我的问题:

<system.runtime.serialization>
        <dataContractSerializer>    
            <declaredTypes>
                <add type="NameSpace.ServiceClientName.ClassNameForWhichKnownTypeIsToBeGiven, AssemblyName">
                    <knownType  type="System.DBNull"></knownType>
                </add>
             </declaredTypes>
        </dataContractSerializer>
</system.runtime.serialization> 

【讨论】:

    【解决方案2】:

    错误消息基本上意味着您的集合包含 DBNull 类型的对象。 WCF 反序列化程序不知道该类型,因此会引发异常。如果您将 KnownTypeAttribute 添加到您的数据合同中并在其参数中包含 DBNull 就可以了。

    有点像这样:

    [CollectionDataContract]
    [KnownType(typeof(DBNull))]
    public class YourList : ArrayList {
    }
    

    【讨论】:

    • 感谢 Farawin 的回复!我对 wcf 服务非常陌生。根据您的建议,我在我的类上方添加了 [CollectionDataContract] [KnownType(typeof(PatientInsurance))] 这些属性。但是给我的错误是“Type 'PatientPortal.Model.Data.PatientInsurance'具有 CollectionDataContractAttribute 属性是无效的集合类型,因为它具有 DataContractAttribute 属性。'还有一个问题,什么是 [KnownType(typeof(Player))] 属性中的'Player'。它是属性吗?如果是,我是否需要添加相同的所有其他列的多次属性?
    • Player 类只是一个例子,为了清楚起见,我已经编辑了答案。我相信已知类型只需要是 DataContracts。如果您发布更多代码会有所帮助。
    猜你喜欢
    • 1970-01-01
    • 2013-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-12
    • 1970-01-01
    相关资源
    最近更新 更多