< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Dispatcher.SingleBodyParameterDataContractMessageFormatter
Assembly: CoreWCF.WebHttp
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.WebHttp/src/CoreWCF/Dispatcher/SingleBodyParameterDataContractMessageFormatter.cs
Line coverage
72%
Covered lines: 70
Uncovered lines: 26
Coverable lines: 96
Total lines: 244
Line coverage: 72.9%
Branch coverage
51%
Covered branches: 28
Total branches: 54
Branch coverage: 51.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.cctor()100%11100%
.ctor(...)58.33%121279.16%
UnwrapNullableType(...)50%4466.66%
ReadObject(...)50%4475%
AttachMessageProperties(...)100%22100%
GetInputSerializers()100%11100%
GetOutputSerializer(...)50%6672.72%
IsTypeCollectionInterface(...)50%121244.44%
ValidateMessageFormatProperty(...)0%660%
ValidateType(...)75%4487.5%
CreateInputSerializers(...)50%2283.33%
CreateSerializer(...)100%22100%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.WebHttp/src/CoreWCF/Dispatcher/SingleBodyParameterDataContractMessageFormatter.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.Runtime.Serialization;
 9using System.Runtime.Serialization.Json;
 10using CoreWCF.Channels;
 11using CoreWCF.Description;
 12
 13namespace CoreWCF.Dispatcher
 14{
 15    internal class SingleBodyParameterDataContractMessageFormatter : SingleBodyParameterMessageFormatter
 16    {
 117        private static readonly Type s_typeOfNullable = typeof(Nullable<>);
 118        private static readonly Type[] s_collectionDataContractInterfaces = new Type[] { typeof(IEnumerable), typeof(ILi
 119        private static readonly Type[] s_genericCollectionDataContractInterfaces = new Type[] { typeof(IEnumerable<>), t
 20        private XmlObjectSerializer _cachedOutputSerializer;
 21        private Type _cachedOutputSerializerType;
 22        private readonly bool _ignoreExtensionData;
 23        private XmlObjectSerializer[] _inputSerializers;
 24        private readonly IList<Type> _knownTypes;
 25        private readonly int _maxItemsInObjectGraph;
 26        private readonly Type _parameterDataContractType;
 27        private readonly object _thisLock;
 28        private readonly bool _useJsonFormat;
 29        private readonly bool _isParameterCollectionInterfaceDataContract;
 30        private readonly bool _isQueryable;
 31
 32        public SingleBodyParameterDataContractMessageFormatter(OperationDescription operation, Type parameterType, bool 
 27233            : base(operation, isRequestFormatter, "DataContractSerializer")
 34        {
 27235            if (operation == null)
 36            {
 037                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(operation));
 38            }
 39
 27240            if (parameterType == null)
 41            {
 042                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(parameterType));
 43            }
 44
 27245            if (dcsob == null)
 46            {
 047                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(dcsob));
 48            }
 49
 27250            _parameterDataContractType = DataContractHelpers.GetSubstituteDataContractType(parameterType, out _isQueryab
 27251            _isParameterCollectionInterfaceDataContract = IsTypeCollectionInterface(_parameterDataContractType);
 27252            List<Type> tmp = new List<Type>();
 27253            if (operation.KnownTypes != null)
 54            {
 54455                foreach (Type knownType in operation.KnownTypes)
 56                {
 057                    tmp.Add(knownType);
 58                }
 59            }
 60
 27261            Type nullableType = UnwrapNullableType(_parameterDataContractType);
 27262            if (nullableType != _parameterDataContractType)
 63            {
 064                tmp.Add(nullableType);
 65            }
 66
 27267            _ignoreExtensionData = dcsob.IgnoreExtensionDataObject;
 27268            _maxItemsInObjectGraph = dcsob.MaxItemsInObjectGraph;
 27269            _knownTypes = tmp.AsReadOnly();
 27270            ValidateType(_parameterDataContractType, _knownTypes);
 71
 27272            _useJsonFormat = useJsonFormat;
 27273            CreateInputSerializers(_parameterDataContractType);
 74
 27275            _thisLock = new object();
 27276        }
 77
 78        internal static Type UnwrapNullableType(Type type)
 79        {
 27280            while (type.IsGenericType && type.GetGenericTypeDefinition() == s_typeOfNullable)
 81            {
 082                type = type.GetGenericArguments()[0];
 83            }
 84
 27285            return type;
 86        }
 87
 88        // The logic of this method should be kept the same as
 89        // System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.PartInfo.ReadObject
 90        protected override object ReadObject(Message message)
 91        {
 592            object val = base.ReadObject(message);
 593            if (_isQueryable && val != null)
 94            {
 095                return Queryable.AsQueryable((IEnumerable)val);
 96            }
 97
 598            return val;
 99        }
 100
 101        protected override void AttachMessageProperties(Message message, bool isRequest)
 102        {
 26103            if (_useJsonFormat)
 104            {
 24105                message.Properties.Add(WebBodyFormatMessageProperty.Name, WebBodyFormatMessageProperty.JsonProperty);
 106            }
 26107        }
 108
 109        protected override XmlObjectSerializer[] GetInputSerializers()
 110        {
 5111            return _inputSerializers;
 112        }
 113
 114        protected override XmlObjectSerializer GetOutputSerializer(Type type)
 115        {
 26116            lock (_thisLock)
 117            {
 118                // if we already have a serializer for this type reuse it
 26119                if (_cachedOutputSerializerType != type)
 120                {
 121                    Type typeForSerializer;
 26122                    if (_isParameterCollectionInterfaceDataContract)
 123                    {
 124                        // if the parameterType is a collection interface, ensure the type implements it
 0125                        if (!_parameterDataContractType.IsAssignableFrom(type))
 126                        {
 0127                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.Form
 128                        }
 0129                        typeForSerializer = _parameterDataContractType;
 130                    }
 131                    else
 132                    {
 26133                        typeForSerializer = GetTypeForSerializer(type, _parameterDataContractType, _knownTypes);
 134                    }
 26135                    _cachedOutputSerializer = CreateSerializer(typeForSerializer);
 26136                    _cachedOutputSerializerType = type;
 137                }
 138
 26139                return _cachedOutputSerializer;
 140            }
 26141        }
 142
 143        private static bool IsTypeCollectionInterface(Type parameterType)
 144        {
 272145            if (parameterType.IsGenericType && parameterType.IsInterface)
 146            {
 0147                Type genericTypeDef = parameterType.GetGenericTypeDefinition();
 0148                foreach (Type type in s_genericCollectionDataContractInterfaces)
 149                {
 0150                    if (genericTypeDef == type)
 151                    {
 0152                        return true;
 153                    }
 154                }
 155            }
 156
 2720157            foreach (Type type in s_collectionDataContractInterfaces)
 158            {
 1088159                if (parameterType == type)
 160                {
 0161                    return true;
 162                }
 163            }
 164
 272165            return false;
 166        }
 167
 168        protected override void ValidateMessageFormatProperty(Message message)
 169        {
 0170            if (_useJsonFormat)
 171            {
 172                // useJsonFormat is always false in the green bits
 0173                message.Properties.TryGetValue(WebBodyFormatMessageProperty.Name, out object prop);
 0174                WebBodyFormatMessageProperty formatProperty = (prop as WebBodyFormatMessageProperty);
 0175                if (formatProperty == null)
 176                {
 0177                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.Format(
 178                }
 0179                if (formatProperty.Format != WebContentFormat.Json)
 180                {
 0181                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.Format(
 182                }
 183            }
 184            else
 185            {
 0186                base.ValidateMessageFormatProperty(message);
 187            }
 0188        }
 189
 190        private static void ValidateType(Type parameterType, IEnumerable<Type> knownTypes)
 191        {
 272192            XsdDataContractExporter dataContractExporter = new XsdDataContractExporter();
 272193            if (knownTypes != null)
 194            {
 272195                ExportOptions options = new ExportOptions();
 196
 544197                foreach (Type knownType in knownTypes)
 198                {
 0199                    options.KnownTypes.Add(knownType);
 200                }
 201
 272202                dataContractExporter.Options = options;
 203            }
 204
 272205            dataContractExporter.GetSchemaTypeName(parameterType); // throws if parameterType is not a valid data contra
 272206        }
 207
 208        private void CreateInputSerializers(Type type)
 209        {
 272210            List<XmlObjectSerializer> tmp = new List<XmlObjectSerializer>();
 272211            tmp.Add(CreateSerializer(type));
 544212            foreach (Type knownType in _knownTypes)
 213            {
 0214                tmp.Add(CreateSerializer(knownType));
 215            }
 216
 272217            _inputSerializers = tmp.ToArray();
 272218        }
 219
 220        private XmlObjectSerializer CreateSerializer(Type type)
 221        {
 298222            if (_useJsonFormat)
 223            {
 160224                return new DataContractJsonSerializer(type, new DataContractJsonSerializerSettings
 160225                {
 160226                    KnownTypes = _knownTypes,
 160227                    MaxItemsInObjectGraph = _maxItemsInObjectGraph,
 160228                    IgnoreExtensionDataObject = _ignoreExtensionData,
 160229                    EmitTypeInformation = EmitTypeInformation.AsNeeded
 160230                });
 231            }
 232            else
 233            {
 138234                return new DataContractSerializer(type, new DataContractSerializerSettings
 138235                {
 138236                    KnownTypes = _knownTypes,
 138237                    MaxItemsInObjectGraph = _maxItemsInObjectGraph,
 138238                    IgnoreExtensionDataObject = _ignoreExtensionData,
 138239                    PreserveObjectReferences = false
 138240                });
 241            }
 242        }
 243    }
 244}