< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Dispatcher.DataContractSerializerDefaults
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Dispatcher/DataContractSerializerOperationFormatter.cs
Line coverage
64%
Covered lines: 11
Uncovered lines: 6
Coverable lines: 17
Total lines: 674
Line coverage: 64.7%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
CreateSerializer(...)100%11100%
CreateSerializer(...)100%11100%
CreateSerializer(...)100%11100%
CreateSerializer(...)100%11100%
CreateSerializer(...)100%110%
CreateSerializer(...)100%110%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Dispatcher/DataContractSerializerOperationFormatter.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.Collections;
 6using System.Collections.Generic;
 7using System.Linq;
 8using System.Reflection;
 9using System.Runtime.Serialization;
 10using System.Xml;
 11using CoreWCF.Channels;
 12using CoreWCF.Description;
 13using CoreWCF.Runtime.Serialization;
 14
 15namespace CoreWCF.Dispatcher
 16{
 17    internal static class DataContractSerializerDefaults
 18    {
 19        internal const bool IgnoreExtensionDataObject = false;
 20        internal const int MaxItemsInObjectGraph = int.MaxValue;
 21
 22        internal static DataContractSerializer CreateSerializer(Type type, int maxItems)
 23        {
 36424            return CreateSerializer(type, null, maxItems);
 25        }
 26
 27        internal static DataContractSerializer CreateSerializer(Type type, IList<Type> knownTypes, int maxItems)
 28        {
 39529            return new DataContractSerializer(
 39530                type,
 39531                knownTypes);
 32        }
 33
 34        internal static DataContractSerializer CreateSerializer(Type type, string rootName, string rootNs, int maxItems)
 35        {
 336            return CreateSerializer(type, null, rootName, rootNs, maxItems);
 37        }
 38
 39        internal static DataContractSerializer CreateSerializer(Type type, IList<Type> knownTypes, string rootName, stri
 40        {
 3341            XmlDictionary dictionary = new XmlDictionary(2);
 3342            return new DataContractSerializer(
 3343                type,
 3344                dictionary.Add(rootName),
 3345                dictionary.Add(rootNs),
 3346                knownTypes);
 47        }
 48
 49        internal static DataContractSerializer CreateSerializer(Type type, XmlDictionaryString rootName, XmlDictionarySt
 50        {
 051            return CreateSerializer(type, null, rootName, rootNs, maxItems);
 52        }
 53
 54        internal static DataContractSerializer CreateSerializer(Type type, IList<Type> knownTypes, XmlDictionaryString r
 55        {
 056            return new DataContractSerializer(
 057                type,
 058                rootName,
 059                rootNs,
 060                knownTypes);
 61        }
 62    }
 63
 64    public class DataContractSerializerOperationFormatter : OperationFormatter
 65    {
 66        private static readonly Type s_typeOfIQueryable = typeof(IQueryable);
 67        private static readonly Type s_typeOfIQueryableGeneric = typeof(IQueryable<>);
 68        private static readonly Type s_typeOfIEnumerable = typeof(IEnumerable);
 69        private static readonly Type s_typeOfIEnumerableGeneric = typeof(IEnumerable<>);
 70
 71        protected MessageInfo requestMessageInfo;
 72        protected MessageInfo replyMessageInfo;
 73        private readonly IList<Type> _knownTypes;
 74
 75        private IXsdDataContractExporter _dataContractExporter;
 76        private readonly DataContractSerializerOperationBehavior _serializerFactory;
 77
 78        public DataContractSerializerOperationFormatter(OperationDescription description, DataContractFormatAttribute da
 79            DataContractSerializerOperationBehavior serializerFactory)
 80            : base(description, dataContractFormatAttribute.Style == OperationFormatStyle.Rpc, false/*isEncoded*/)
 81        {
 82            if (description == null)
 83            {
 84                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(description));
 85            }
 86
 87            _serializerFactory = serializerFactory ?? new DataContractSerializerOperationBehavior(description);
 88            foreach (Type type in description.KnownTypes)
 89            {
 90                if (_knownTypes == null)
 91                {
 92                    _knownTypes = new List<Type>();
 93                }
 94
 95                if (type == null)
 96                {
 97                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR
 98                }
 99
 100                ValidateDataContractType(type);
 101                _knownTypes.Add(type);
 102            }
 103            requestMessageInfo = CreateMessageInfo(dataContractFormatAttribute, RequestDescription, _serializerFactory);
 104            if (ReplyDescription != null)
 105            {
 106                replyMessageInfo = CreateMessageInfo(dataContractFormatAttribute, ReplyDescription, _serializerFactory);
 107            }
 108        }
 109
 110        private MessageInfo CreateMessageInfo(DataContractFormatAttribute dataContractFormatAttribute,
 111            MessageDescription messageDescription, DataContractSerializerOperationBehavior serializerFactory)
 112        {
 113            if (messageDescription.IsUntypedMessage)
 114            {
 115                return null;
 116            }
 117
 118            MessageInfo messageInfo = new MessageInfo();
 119
 120            MessageBodyDescription body = messageDescription.Body;
 121            if (body.WrapperName != null)
 122            {
 123                messageInfo.WrapperName = AddToDictionary(body.WrapperName);
 124                messageInfo.WrapperNamespace = AddToDictionary(body.WrapperNamespace);
 125            }
 126            MessagePartDescriptionCollection parts = body.Parts;
 127            messageInfo.BodyParts = new PartInfo[parts.Count];
 128            for (int i = 0; i < parts.Count; i++)
 129            {
 130                messageInfo.BodyParts[i] = CreatePartInfo(parts[i], dataContractFormatAttribute.Style, serializerFactory
 131            }
 132
 133            if (IsValidReturnValue(messageDescription.Body.ReturnValue))
 134            {
 135                messageInfo.ReturnPart = CreatePartInfo(messageDescription.Body.ReturnValue, dataContractFormatAttribute
 136            }
 137
 138            messageInfo.HeaderDescriptionTable = new MessageHeaderDescriptionTable();
 139            messageInfo.HeaderParts = new PartInfo[messageDescription.Headers.Count];
 140            for (int i = 0; i < messageDescription.Headers.Count; i++)
 141            {
 142                MessageHeaderDescription headerDescription = messageDescription.Headers[i];
 143                if (headerDescription.IsUnknownHeaderCollection)
 144                {
 145                    messageInfo.UnknownHeaderDescription = headerDescription;
 146                }
 147                else
 148                {
 149                    ValidateDataContractType(headerDescription.Type);
 150                    messageInfo.HeaderDescriptionTable.Add(headerDescription.Name, headerDescription.Namespace, headerDe
 151                }
 152                messageInfo.HeaderParts[i] = CreatePartInfo(headerDescription, OperationFormatStyle.Document, serializer
 153            }
 154            messageInfo.AnyHeaders = messageInfo.UnknownHeaderDescription != null || messageInfo.HeaderDescriptionTable.
 155            return messageInfo;
 156        }
 157
 158        private void ValidateDataContractType(Type type)
 159        {
 160            if (_dataContractExporter == null)
 161            {
 162                _dataContractExporter = XsdDataContractExporterFactory.Create();
 163                //if (_serializerFactory != null && _serializerFactory.DataContractSurrogate != null)
 164                //{
 165                //    ExportOptions options = new ExportOptions();
 166                //    options.DataContractSurrogate = serializerFactory.DataContractSurrogate;
 167                //    dataContractExporter.Options = options;
 168                //}
 169            }
 170            _dataContractExporter.GetSchemaTypeName(type); //Throws if the type is not a valid data contract
 171        }
 172
 173        private PartInfo CreatePartInfo(MessagePartDescription part, OperationFormatStyle style, DataContractSerializerO
 174        {
 175            string ns = (style == OperationFormatStyle.Rpc || part.Namespace == null) ? string.Empty : part.Namespace;
 176            PartInfo partInfo = new PartInfo(part, AddToDictionary(part.Name), AddToDictionary(ns), _knownTypes, seriali
 177            ValidateDataContractType(partInfo.ContractType);
 178            return partInfo;
 179        }
 180
 181        protected override void AddHeadersToMessage(Message message, MessageDescription messageDescription, object[] par
 182        {
 183            MessageInfo messageInfo = isRequest ? requestMessageInfo : replyMessageInfo;
 184            PartInfo[] headerParts = messageInfo.HeaderParts;
 185            if (headerParts == null || headerParts.Length == 0)
 186            {
 187                return;
 188            }
 189
 190            MessageHeaders headers = message.Headers;
 191            for (int i = 0; i < headerParts.Length; i++)
 192            {
 193                PartInfo headerPart = headerParts[i];
 194                MessageHeaderDescription headerDescription = (MessageHeaderDescription)headerPart.Description;
 195                object headerValue = parameters[headerDescription.Index];
 196
 197                if (headerDescription.Multiple)
 198                {
 199                    if (headerValue != null)
 200                    {
 201                        bool isXmlElement = headerDescription.Type == typeof(XmlElement);
 202                        foreach (object headerItemValue in (IEnumerable)headerValue)
 203                        {
 204                            AddMessageHeaderForParameter(headers, headerPart, message.Version, headerItemValue, isXmlEle
 205                        }
 206                    }
 207                }
 208                else
 209                {
 210                    AddMessageHeaderForParameter(headers, headerPart, message.Version, headerValue, false/*isXmlElement*
 211                }
 212            }
 213        }
 214
 215        private void AddMessageHeaderForParameter(MessageHeaders headers, PartInfo headerPart, MessageVersion messageVer
 216        {
 217            MessageHeaderDescription headerDescription = (MessageHeaderDescription)headerPart.Description;
 218            object valueToSerialize = GetContentOfMessageHeaderOfT(headerDescription, parameterValue, out bool mustUnder
 219
 220            if (isXmlElement)
 221            {
 222                if (valueToSerialize == null)
 223                {
 224                    return;
 225                }
 226
 227                XmlElement xmlElement = (XmlElement)valueToSerialize;
 228                headers.Add(new XmlElementMessageHeader(this, messageVersion, xmlElement.LocalName, xmlElement.Namespace
 229                return;
 230            }
 231            headers.Add(new DataContractSerializerMessageHeader(headerPart, valueToSerialize, mustUnderstand, actor, rel
 232        }
 233
 234        protected override void SerializeBody(XmlDictionaryWriter writer, MessageVersion version, string action, Message
 235        {
 236            if (writer == null)
 237            {
 238                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(writer)));
 239            }
 240
 241            if (parameters == null)
 242            {
 243                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(parameters)))
 244            }
 245
 246            MessageInfo messageInfo;
 247            if (isRequest)
 248            {
 249                messageInfo = requestMessageInfo;
 250            }
 251            else
 252            {
 253                messageInfo = replyMessageInfo;
 254            }
 255
 256            if (messageInfo.WrapperName != null)
 257            {
 258                writer.WriteStartElement(messageInfo.WrapperName, messageInfo.WrapperNamespace);
 259            }
 260
 261            if (messageInfo.ReturnPart != null)
 262            {
 263                SerializeParameter(writer, messageInfo.ReturnPart, returnValue);
 264            }
 265
 266            SerializeParameters(writer, messageInfo.BodyParts, parameters);
 267            if (messageInfo.WrapperName != null)
 268            {
 269                writer.WriteEndElement();
 270            }
 271        }
 272
 273        private void SerializeParameters(XmlDictionaryWriter writer, PartInfo[] parts, object[] parameters)
 274        {
 275            for (int i = 0; i < parts.Length; i++)
 276            {
 277                PartInfo part = parts[i];
 278                object graph = parameters[part.Description.Index];
 279                SerializeParameter(writer, part, graph);
 280            }
 281        }
 282
 283        private void SerializeParameter(XmlDictionaryWriter writer, PartInfo part, object graph)
 284        {
 285            if (part.Description.Multiple)
 286            {
 287                if (graph != null)
 288                {
 289                    foreach (object item in (IEnumerable)graph)
 290                    {
 291                        SerializeParameterPart(writer, part, item);
 292                    }
 293                }
 294            }
 295            else
 296            {
 297                SerializeParameterPart(writer, part, graph);
 298            }
 299        }
 300
 301        private void SerializeParameterPart(XmlDictionaryWriter writer, PartInfo part, object graph)
 302        {
 303            try
 304            {
 305                part.Serializer.WriteObject(writer, graph);
 306            }
 307            catch (SerializationException sx)
 308            {
 309                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
 310                    SR.Format(SR.SFxInvalidMessageBodyErrorSerializingParameter, part.Description.Namespace, part.Descri
 311            }
 312        }
 313
 314        protected override void GetHeadersFromMessage(Message message, MessageDescription messageDescription, object[] p
 315        {
 316            MessageInfo messageInfo = isRequest ? requestMessageInfo : replyMessageInfo;
 317            if (!messageInfo.AnyHeaders)
 318            {
 319                return;
 320            }
 321
 322            MessageHeaders headers = message.Headers;
 323            KeyValuePair<Type, ArrayList>[] multipleHeaderValues = null;
 324            ArrayList elementList = null;
 325            if (messageInfo.UnknownHeaderDescription != null)
 326            {
 327                elementList = new ArrayList();
 328            }
 329
 330            for (int i = 0; i < headers.Count; i++)
 331            {
 332                MessageHeaderInfo header = headers[i];
 333                MessageHeaderDescription headerDescription = messageInfo.HeaderDescriptionTable.Get(header.Name, header.
 334                if (headerDescription != null)
 335                {
 336                    if (header.MustUnderstand)
 337                    {
 338                        headers.UnderstoodHeaders.Add(header);
 339                    }
 340
 341                    object item = null;
 342                    XmlDictionaryReader headerReader = headers.GetReaderAtHeader(i);
 343                    try
 344                    {
 345                        object dataValue = DeserializeHeaderContents(headerReader, messageDescription, headerDescription
 346                        if (headerDescription.TypedHeader)
 347                        {
 348                            item = TypedHeaderManager.Create(headerDescription.Type, dataValue, headers[i].MustUnderstan
 349                        }
 350                        else
 351                        {
 352                            item = dataValue;
 353                        }
 354                    }
 355                    finally
 356                    {
 357                        headerReader.Dispose();
 358                    }
 359
 360                    if (headerDescription.Multiple)
 361                    {
 362                        if (multipleHeaderValues == null)
 363                        {
 364                            multipleHeaderValues = new KeyValuePair<Type, ArrayList>[parameters.Length];
 365                        }
 366
 367                        if (multipleHeaderValues[headerDescription.Index].Key == null)
 368                        {
 369                            multipleHeaderValues[headerDescription.Index] = new KeyValuePair<System.Type, System.Collect
 370                        }
 371                        multipleHeaderValues[headerDescription.Index].Value.Add(item);
 372                    }
 373                    else
 374                    {
 375                        parameters[headerDescription.Index] = item;
 376                    }
 377                }
 378                else if (messageInfo.UnknownHeaderDescription != null)
 379                {
 380                    MessageHeaderDescription unknownHeaderDescription = messageInfo.UnknownHeaderDescription;
 381                    XmlDictionaryReader headerReader = headers.GetReaderAtHeader(i);
 382                    try
 383                    {
 384                        XmlDocument doc = new XmlDocument();
 385                        object dataValue = doc.ReadNode(headerReader);
 386                        if (dataValue != null && unknownHeaderDescription.TypedHeader)
 387                        {
 388                            dataValue = TypedHeaderManager.Create(unknownHeaderDescription.Type, dataValue, headers[i].M
 389                        }
 390
 391                        elementList.Add(dataValue);
 392                    }
 393                    finally
 394                    {
 395                        headerReader.Dispose();
 396                    }
 397                }
 398            }
 399            if (multipleHeaderValues != null)
 400            {
 401                for (int i = 0; i < parameters.Length; i++)
 402                {
 403                    if (multipleHeaderValues[i].Key != null)
 404                    {
 405                        parameters[i] = multipleHeaderValues[i].Value.ToArray(multipleHeaderValues[i].Key);
 406                    }
 407                }
 408            }
 409            if (messageInfo.UnknownHeaderDescription != null)
 410            {
 411                parameters[messageInfo.UnknownHeaderDescription.Index] = elementList.ToArray(messageInfo.UnknownHeaderDe
 412            }
 413        }
 414
 415        private object DeserializeHeaderContents(XmlDictionaryReader reader, MessageDescription messageDescription, Mess
 416        {
 417            Type dataContractType = GetSubstituteDataContractType(headerDescription.Type, out bool isQueryable);
 418            XmlObjectSerializer serializerLocal = _serializerFactory.CreateSerializer(dataContractType, headerDescriptio
 419            object val = serializerLocal.ReadObject(reader);
 420            if (isQueryable && val != null)
 421            {
 422                return Queryable.AsQueryable((IEnumerable)val);
 423            }
 424            return val;
 425        }
 426
 427        protected override object DeserializeBody(XmlDictionaryReader reader, MessageVersion version, string action, Mes
 428        {
 429            if (reader == null)
 430            {
 431                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(reader)));
 432            }
 433
 434            if (parameters == null)
 435            {
 436                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(parameters)))
 437            }
 438
 439            MessageInfo messageInfo;
 440            if (isRequest)
 441            {
 442                messageInfo = requestMessageInfo;
 443            }
 444            else
 445            {
 446                messageInfo = replyMessageInfo;
 447            }
 448
 449            if (messageInfo.WrapperName != null)
 450            {
 451                if (!reader.IsStartElement(messageInfo.WrapperName, messageInfo.WrapperNamespace))
 452                {
 453                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.Format(SR.SF
 454                }
 455
 456                bool isEmptyElement = reader.IsEmptyElement;
 457                reader.Read();
 458                if (isEmptyElement)
 459                {
 460                    return null;
 461                }
 462            }
 463            object returnValue = null;
 464            if (messageInfo.ReturnPart != null)
 465            {
 466                while (true)
 467                {
 468                    PartInfo part = messageInfo.ReturnPart;
 469                    if (part.Serializer.IsStartObject(reader))
 470                    {
 471                        returnValue = DeserializeParameter(reader, part, isRequest);
 472                        break;
 473                    }
 474                    if (!reader.IsStartElement())
 475                    {
 476                        break;
 477                    }
 478
 479                    TraceAndSkipElement(reader);
 480                }
 481            }
 482            DeserializeParameters(reader, messageInfo.BodyParts, parameters, isRequest);
 483            if (messageInfo.WrapperName != null)
 484            {
 485                reader.ReadEndElement();
 486            }
 487
 488            return returnValue;
 489        }
 490
 491        private void DeserializeParameters(XmlDictionaryReader reader, PartInfo[] parts, object[] parameters, bool isReq
 492        {
 493            int nextPartIndex = 0;
 494            while (reader.IsStartElement())
 495            {
 496                for (int i = nextPartIndex; i < parts.Length; i++)
 497                {
 498                    PartInfo part = parts[i];
 499                    if (part.Serializer.IsStartObject(reader))
 500                    {
 501                        object parameterValue = DeserializeParameter(reader, part, isRequest);
 502                        parameters[part.Description.Index] = parameterValue;
 503                        nextPartIndex = i + 1;
 504                    }
 505                    else
 506                    {
 507                        parameters[part.Description.Index] = null;
 508                    }
 509                }
 510
 511                if (reader.IsStartElement())
 512                {
 513                    TraceAndSkipElement(reader);
 514                }
 515            }
 516        }
 517
 518        private object DeserializeParameter(XmlDictionaryReader reader, PartInfo part, bool isRequest)
 519        {
 520            if (part.Description.Multiple)
 521            {
 522                ArrayList items = new ArrayList();
 523                while (part.Serializer.IsStartObject(reader))
 524                {
 525                    items.Add(DeserializeParameterPart(reader, part, isRequest));
 526                }
 527
 528                return items.ToArray(part.Description.Type);
 529            }
 530            return DeserializeParameterPart(reader, part, isRequest);
 531        }
 532
 533        private object DeserializeParameterPart(XmlDictionaryReader reader, PartInfo part, bool isRequest)
 534        {
 535            object val;
 536            try
 537            {
 538                val = part.ReadObject(reader);
 539            }
 540            catch (System.InvalidOperationException e)
 541            {
 542                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
 543                    SR.Format(SR.SFxInvalidMessageBodyErrorDeserializingParameter, part.Description.Namespace, part.Desc
 544            }
 545            catch (System.Runtime.Serialization.InvalidDataContractException e)
 546            {
 547                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(
 548                    SR.Format(SR.SFxInvalidMessageBodyErrorDeserializingParameter, part.Description.Namespace, part.Desc
 549            }
 550            catch (System.FormatException e)
 551            {
 552                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
 553                    NetDispatcherFaultException.CreateDeserializationFailedFault(
 554                        SR.Format(SR.SFxInvalidMessageBodyErrorDeserializingParameterMore, part.Description.Namespace, p
 555                                     e));
 556            }
 557            catch (System.Runtime.Serialization.SerializationException e)
 558            {
 559                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
 560                    NetDispatcherFaultException.CreateDeserializationFailedFault(
 561                        SR.Format(SR.SFxInvalidMessageBodyErrorDeserializingParameterMore, part.Description.Namespace, p
 562                                     e));
 563            }
 564
 565            return val;
 566        }
 567
 568        internal static Type GetSubstituteDataContractType(Type type, out bool isQueryable)
 569        {
 570            if (type == s_typeOfIQueryable)
 571            {
 572                isQueryable = true;
 573                return s_typeOfIEnumerable;
 574            }
 575
 576            if (type.GetTypeInfo().IsGenericType &&
 577                type.GetGenericTypeDefinition() == s_typeOfIQueryableGeneric)
 578            {
 579                isQueryable = true;
 580                return s_typeOfIEnumerableGeneric.MakeGenericType(type.GetGenericArguments());
 581            }
 582
 583            isQueryable = false;
 584            return type;
 585        }
 586
 587        private class DataContractSerializerMessageHeader : XmlObjectSerializerHeader
 588        {
 589            private readonly PartInfo _headerPart;
 590
 591            public DataContractSerializerMessageHeader(PartInfo headerPart, object headerValue, bool mustUnderstand, str
 592                : base(headerPart.DictionaryName.Value, headerPart.DictionaryNamespace.Value, headerValue, headerPart.Se
 593            {
 594                _headerPart = headerPart;
 595            }
 596
 597            protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
 598            {
 599                //Prefix needed since there may be xsi:type attribute at toplevel with qname value where ns = ""
 600                string prefix = (Namespace == null || Namespace.Length == 0) ? string.Empty : "h";
 601                writer.WriteStartElement(prefix, _headerPart.DictionaryName, _headerPart.DictionaryNamespace);
 602                WriteHeaderAttributes(writer, messageVersion);
 603            }
 604        }
 605
 606
 607        protected class MessageInfo
 608        {
 609            internal PartInfo[] HeaderParts;
 610            public XmlDictionaryString WrapperName;
 611            public XmlDictionaryString WrapperNamespace;
 612            public PartInfo[] BodyParts;
 613            public PartInfo ReturnPart;
 614            internal MessageHeaderDescriptionTable HeaderDescriptionTable;
 615            internal MessageHeaderDescription UnknownHeaderDescription;
 616            internal bool AnyHeaders;
 617        }
 618
 619        protected class PartInfo
 620        {
 621            private XmlObjectSerializer _serializer;
 622            private readonly IList<Type> _knownTypes;
 623            private readonly DataContractSerializerOperationBehavior _serializerFactory;
 624            private readonly bool _isQueryable;
 625
 626            public PartInfo(MessagePartDescription description, XmlDictionaryString dictionaryName, XmlDictionaryString 
 627                IList<Type> knownTypes, DataContractSerializerOperationBehavior behavior)
 628            {
 629                DictionaryName = dictionaryName;
 630                DictionaryNamespace = dictionaryNamespace;
 631                Description = description;
 632                _knownTypes = knownTypes;
 633                _serializerFactory = behavior;
 634
 635                ContractType = GetSubstituteDataContractType(description.Type, out _isQueryable);
 636            }
 637
 638            public Type ContractType { get; }
 639
 640            public MessagePartDescription Description { get; }
 641
 642            public XmlDictionaryString DictionaryName { get; }
 643
 644            public XmlDictionaryString DictionaryNamespace { get; }
 645
 646            public XmlObjectSerializer Serializer
 647            {
 648                get
 649                {
 650                    if (_serializer == null)
 651                    {
 652                        _serializer = _serializerFactory.CreateSerializer(ContractType, DictionaryName, DictionaryNamesp
 653                    }
 654                    return _serializer;
 655                }
 656            }
 657
 658            public object ReadObject(XmlDictionaryReader reader)
 659            {
 660                return ReadObject(reader, Serializer);
 661            }
 662
 663            public object ReadObject(XmlDictionaryReader reader, XmlObjectSerializer serializer)
 664            {
 665                object val = _serializer.ReadObject(reader, false /* verifyObjectName */);
 666                if (_isQueryable && val != null)
 667                {
 668                    return Queryable.AsQueryable((IEnumerable)val);
 669                }
 670                return val;
 671            }
 672        }
 673    }
 674}