WCF服务异常:在尝试反序列化消息时,格式化程序抛出了异常。

4

格式化程序在尝试反序列化消息时引发了异常:

尝试反序列化参数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;
        }

class总是由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;
            }
        }
    }
}

.


1
你需要解决这个问题的所有信息都在异常消息中... 你需要我们提供什么? - Bun
你能够发布一下你的web服务所接收的类以及web服务本身吗? - Nzall
你好,Nate Kerkhofs!谢谢您的回复.. :) 我已经更新了我的问题。 - user632299
2个回答

5

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

 [ServiceKnownType(typeof(System.DBNull))] 

因此,当反序列化客户端时,并没有得到 System.DBNull 类型。我们需要在客户端的配置文件中添加知名类型。

这是解决我的问题所需的客户端配置:

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

0

这个错误信息基本上意味着你的集合包含了一个 DBNull 类型的对象。WCF 反序列化程序不知道该类型,因此会抛出异常。如果你在数据契约中添加 KnownTypeAttribute,并将 DBNull 包含在它的参数中,那么问题就解决了。

就像这样:

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

谢谢Farawin的回复!我对wcf服务非常陌生。根据您的建议,我在我的类上方添加了[CollectionDataContract] [KnownType(typeof(PatientInsurance))]这些属性。但是它给出了一个错误:“类型'PatientPortal.Model.Data.PatientInsurance'具有CollectionDataContractAttribute属性,因此是无效的集合类型,因为它具有DataContractAttribute属性。”还有一个问题,[KnownType(typeof(Player))]属性中的“Player”是什么?它是属性吗?如果是,我需要为所有其他列多次添加相同的属性吗? - user632299
Player类只是一个示例,我已经编辑了答案以使其更清晰。我认为已知类型只需要是数据合同。如果您发布更多的代码将会有所帮助。 - Farawin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接