< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Channels.MessageFault
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Channels/MessageFault.cs
Line coverage
74%
Covered lines: 117
Uncovered lines: 40
Coverable lines: 157
Total lines: 740
Line coverage: 74.5%
Branch coverage
65%
Covered branches: 50
Total branches: 76
Branch coverage: 65.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
CreateFault(...)100%11100%
CreateFault(...)100%11100%
CreateFault(...)50%22100%
CreateFault(...)50%8855.55%
CreateFault(...)25%8837.5%
GetDetail()100%11100%
GetDetail(...)62.5%8877.77%
GetReaderAtDetailContents()50%2266.66%
OnWriteDetail(...)100%11100%
OnWriteStartDetail(...)50%4450%
OnGetReaderAtDetailContents()100%11100%
WriteTo(...)100%110%
WriteTo(...)50%101054.54%
WriteToNone(...)100%110%
WriteTo12Driver(...)75%8890.47%
WriteFaultCode12Driver(...)100%1010100%
WriteTo12(...)100%11100%
WriteTo11(...)81.25%161690%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Channels/MessageFault.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.Generic;
 6using System.Globalization;
 7using System.Runtime.Serialization;
 8using System.Xml;
 9using CoreWCF.Diagnostics;
 10using CoreWCF.Dispatcher;
 11
 12namespace CoreWCF.Channels
 13{
 14    public abstract class MessageFault
 15    {
 16        internal static MessageFault CreateFault(FaultCode code, string reason)
 17        {
 218            return CreateFault(code, new FaultReason(reason));
 19        }
 20
 21        internal static MessageFault CreateFault(FaultCode code, FaultReason reason)
 22        {
 14223            return CreateFault(code, reason, null, null, "", "");
 24        }
 25
 26        internal static MessageFault CreateFault(FaultCode code, FaultReason reason, object detail)
 27        {
 428            return CreateFault(code, reason, detail, DataContractSerializerDefaults.CreateSerializer(
 429                (detail == null ? typeof(object) : detail.GetType()), int.MaxValue/*maxItems*/), "", "");
 30        }
 31
 32        public static MessageFault CreateFault(FaultCode code, FaultReason reason, object detail, XmlObjectSerializer se
 33        {
 33434            if (code == null)
 35            {
 036                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(code));
 37            }
 38
 33439            if (reason == null)
 40            {
 041                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(reason));
 42            }
 43
 33444            if (actor == null)
 45            {
 046                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(actor));
 47            }
 48
 33449            if (node == null)
 50            {
 051                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(node));
 52            }
 53
 33454            return new XmlObjectSerializerFault(code, reason, detail, serializer, actor, node);
 55        }
 56
 57        public static MessageFault CreateFault(Message message, int maxBufferSize)
 58        {
 259            if (message == null)
 60            {
 061                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(message));
 62            }
 63
 264            XmlDictionaryReader reader = message.GetReaderAtBodyContents();
 265            using (reader)
 66            {
 67                try
 68                {
 269                    EnvelopeVersion envelopeVersion = message.Version.Envelope;
 70                    MessageFault fault;
 271                    if (envelopeVersion == EnvelopeVersion.Soap12)
 72                    {
 273                        fault = ReceivedFault.CreateFault12(reader, maxBufferSize);
 74                    }
 075                    else if (envelopeVersion == EnvelopeVersion.Soap11)
 76                    {
 077                        fault = ReceivedFault.CreateFault11(reader, maxBufferSize);
 78                    }
 079                    else if (envelopeVersion == EnvelopeVersion.None)
 80                    {
 081                        fault = ReceivedFault.CreateFaultNone(reader, maxBufferSize);
 82                    }
 83                    else
 84                    {
 085                        throw TraceUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.EnvelopeVersionUn
 86                    }
 287                    message.ReadFromBodyContentsToEnd(reader);
 288                    return fault;
 89                }
 090                catch (InvalidOperationException e)
 91                {
 092                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
 093                        SR.SFxErrorDeserializingFault, e));
 94                }
 095                catch (FormatException e)
 96                {
 097                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
 098                        SR.SFxErrorDeserializingFault, e));
 99                }
 0100                catch (XmlException e)
 101                {
 0102                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
 0103                        SR.SFxErrorDeserializingFault, e));
 104                }
 105            }
 2106        }
 107
 108        public virtual string Actor
 109        {
 110            get
 111            {
 0112                return "";
 113            }
 114        }
 115
 116        public abstract FaultCode Code { get; }
 117        public virtual string Node
 118        {
 119            get
 120            {
 0121                return "";
 122            }
 123        }
 124
 125        public abstract bool HasDetail { get; }
 126
 127        public abstract FaultReason Reason { get; }
 128
 129        public T GetDetail<T>()
 130        {
 4131            return GetDetail<T>(DataContractSerializerDefaults.CreateSerializer(typeof(T), int.MaxValue/*maxItems*/));
 132        }
 133
 134        public T GetDetail<T>(XmlObjectSerializer serializer)
 135        {
 4136            if (serializer == null)
 137            {
 0138                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(serializer));
 139            }
 140
 4141            XmlDictionaryReader reader = GetReaderAtDetailContents();
 4142            T value = (T)serializer.ReadObject(reader);
 4143            if (!reader.EOF)
 144            {
 4145                reader.MoveToContent();
 4146                if (reader.NodeType != XmlNodeType.EndElement && !reader.EOF)
 147                {
 0148                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.ExtraContentIsPrese
 149                }
 150            }
 4151            return value;
 152        }
 153
 154        public XmlDictionaryReader GetReaderAtDetailContents()
 155        {
 4156            if (!HasDetail)
 157            {
 0158                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.FaultDoesNotH
 159            }
 160
 4161            return OnGetReaderAtDetailContents();
 162        }
 163
 164        protected virtual void OnWriteDetail(XmlDictionaryWriter writer, EnvelopeVersion version)
 165        {
 259166            OnWriteStartDetail(writer, version);
 259167            OnWriteDetailContents(writer);
 259168            writer.WriteEndElement();
 259169        }
 170
 171        protected virtual void OnWriteStartDetail(XmlDictionaryWriter writer, EnvelopeVersion version)
 172        {
 259173            if (version == EnvelopeVersion.Soap12)
 174            {
 184175                writer.WriteStartElement(XD.Message12Dictionary.FaultDetail, XD.Message12Dictionary.Namespace);
 176            }
 75177            else if (version == EnvelopeVersion.Soap11)
 178            {
 75179                writer.WriteStartElement(XD.Message11Dictionary.FaultDetail, XD.Message11Dictionary.FaultNamespace);
 180            }
 181            else
 182            {
 0183                writer.WriteStartElement(XD.Message12Dictionary.FaultDetail, XD.MessageDictionary.Namespace);
 184            }
 0185        }
 186
 187        protected abstract void OnWriteDetailContents(XmlDictionaryWriter writer);
 188
 189        protected virtual XmlDictionaryReader OnGetReaderAtDetailContents()
 190        {
 2191            XmlBuffer detailBuffer = new XmlBuffer(int.MaxValue);
 2192            XmlDictionaryWriter writer = detailBuffer.OpenSection(XmlDictionaryReaderQuotas.Max);
 2193            OnWriteDetail(writer, EnvelopeVersion.Soap12);  // Wrap in soap 1.2 by default
 2194            detailBuffer.CloseSection();
 2195            detailBuffer.Close();
 2196            XmlDictionaryReader reader = detailBuffer.GetReader(0);
 2197            reader.Read(); // Skip the detail element
 2198            return reader;
 199        }
 200
 201        internal void WriteTo(XmlWriter writer, EnvelopeVersion version)
 202        {
 0203            WriteTo(XmlDictionaryWriter.CreateDictionaryWriter(writer), version);
 0204        }
 205
 206        internal void WriteTo(XmlDictionaryWriter writer, EnvelopeVersion version)
 207        {
 329208            if (writer == null)
 209            {
 0210                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(writer));
 211            }
 212
 329213            if (version == null)
 214            {
 0215                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(version));
 216            }
 217
 329218            if (version == EnvelopeVersion.Soap12)
 219            {
 225220                WriteTo12(writer);
 221            }
 104222            else if (version == EnvelopeVersion.Soap11)
 223            {
 104224                WriteTo11(writer);
 225            }
 0226            else if (version == EnvelopeVersion.None)
 227            {
 0228                WriteToNone(writer);
 229            }
 230            else
 231            {
 0232                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.Env
 233            }
 234        }
 235
 236        private void WriteToNone(XmlDictionaryWriter writer)
 237        {
 0238            WriteTo12Driver(writer, EnvelopeVersion.None);
 0239        }
 240
 241        private void WriteTo12Driver(XmlDictionaryWriter writer, EnvelopeVersion version)
 242        {
 225243            writer.WriteStartElement(XD.MessageDictionary.Fault, version.DictionaryNamespace);
 225244            writer.WriteStartElement(XD.Message12Dictionary.FaultCode, version.DictionaryNamespace);
 225245            WriteFaultCode12Driver(writer, Code, version);
 225246            writer.WriteEndElement();
 225247            writer.WriteStartElement(XD.Message12Dictionary.FaultReason, version.DictionaryNamespace);
 225248            FaultReason reason = Reason;
 1080249            for (int i = 0; i < reason.Translations.Count; i++)
 250            {
 315251                FaultReasonText text = reason.Translations[i];
 315252                writer.WriteStartElement(XD.Message12Dictionary.FaultText, version.DictionaryNamespace);
 315253                writer.WriteAttributeString("xml", "lang", XmlUtil.XmlNs, text.XmlLang);
 315254                writer.WriteString(text.Text);
 315255                writer.WriteEndElement();
 256            }
 225257            writer.WriteEndElement();
 225258            if (Node.Length > 0)
 259            {
 0260                writer.WriteElementString(XD.Message12Dictionary.FaultNode, version.DictionaryNamespace, Node);
 261            }
 262
 225263            if (Actor.Length > 0)
 264            {
 0265                writer.WriteElementString(XD.Message12Dictionary.FaultRole, version.DictionaryNamespace, Actor);
 266            }
 267
 225268            if (HasDetail)
 269            {
 182270                OnWriteDetail(writer, version);
 271            }
 225272            writer.WriteEndElement();
 225273        }
 274
 275        private void WriteFaultCode12Driver(XmlDictionaryWriter writer, FaultCode faultCode, EnvelopeVersion version)
 276        {
 269277            writer.WriteStartElement(XD.Message12Dictionary.FaultValue, version.DictionaryNamespace);
 278            string name;
 269279            if (faultCode.IsSenderFault)
 280            {
 42281                name = version.SenderFaultName;
 282            }
 227283            else if (faultCode.IsReceiverFault)
 284            {
 4285                name = version.ReceiverFaultName;
 286            }
 287            else
 288            {
 223289                name = faultCode.Name;
 290            }
 291
 292            string ns;
 269293            if (faultCode.IsPredefinedFault)
 294            {
 225295                ns = version.Namespace;
 296            }
 297            else
 298            {
 44299                ns = faultCode.Namespace;
 300            }
 301
 269302            string prefix = writer.LookupPrefix(ns);
 269303            if (prefix == null)
 304            {
 42305                writer.WriteAttributeString("xmlns", "a", XmlUtil.XmlNsNs, ns);
 306            }
 307
 269308            writer.WriteQualifiedName(name, ns);
 269309            writer.WriteEndElement();
 310
 269311            if (faultCode.SubCode != null)
 312            {
 44313                writer.WriteStartElement(XD.Message12Dictionary.FaultSubcode, version.DictionaryNamespace);
 44314                WriteFaultCode12Driver(writer, faultCode.SubCode, version);
 44315                writer.WriteEndElement();
 316            }
 269317        }
 318
 319        private void WriteTo12(XmlDictionaryWriter writer)
 320        {
 225321            WriteTo12Driver(writer, EnvelopeVersion.Soap12);
 225322        }
 323
 324        private void WriteTo11(XmlDictionaryWriter writer)
 325        {
 104326            writer.WriteStartElement(XD.MessageDictionary.Fault, XD.Message11Dictionary.Namespace);
 104327            writer.WriteStartElement(XD.Message11Dictionary.FaultCode, XD.Message11Dictionary.FaultNamespace);
 328
 104329            FaultCode faultCode = Code;
 104330            if (faultCode.SubCode != null)
 331            {
 32332                faultCode = faultCode.SubCode;
 333            }
 334
 335            string name;
 104336            if (faultCode.IsSenderFault)
 337            {
 72338                name = "Client";
 339            }
 32340            else if (faultCode.IsReceiverFault)
 341            {
 0342                name = "Server";
 343            }
 344            else
 345            {
 32346                name = faultCode.Name;
 347            }
 348
 349            string ns;
 104350            if (faultCode.IsPredefinedFault)
 351            {
 72352                ns = Message11Strings.Namespace;
 353            }
 354            else
 355            {
 32356                ns = faultCode.Namespace;
 357            }
 358
 104359            string prefix = writer.LookupPrefix(ns);
 104360            if (prefix == null)
 361            {
 32362                writer.WriteAttributeString("xmlns", "a", XmlUtil.XmlNsNs, ns);
 363            }
 364
 104365            writer.WriteQualifiedName(name, ns);
 104366            writer.WriteEndElement();
 104367            FaultReasonText translation = Reason.Translations[0];
 104368            writer.WriteStartElement(XD.Message11Dictionary.FaultString, XD.Message11Dictionary.FaultNamespace);
 104369            if (translation.XmlLang.Length > 0)
 370            {
 0371                writer.WriteAttributeString("xml", "lang", XmlUtil.XmlNs, translation.XmlLang);
 372            }
 373
 104374            writer.WriteString(translation.Text);
 104375            writer.WriteEndElement();
 104376            if (Actor.Length > 0)
 377            {
 0378                writer.WriteElementString(XD.Message11Dictionary.FaultActor, XD.Message11Dictionary.FaultNamespace, Acto
 379            }
 380
 104381            if (HasDetail)
 382            {
 75383                OnWriteDetail(writer, EnvelopeVersion.Soap11);
 384            }
 104385            writer.WriteEndElement();
 104386        }
 387    }
 388
 389    internal class XmlObjectSerializerFault : MessageFault
 390    {
 391        private readonly FaultCode _code;
 392        private readonly FaultReason _reason;
 393        private readonly string _actor;
 394        private readonly string _node;
 395        private readonly object _detail;
 396        private readonly XmlObjectSerializer _serializer;
 397
 398        public XmlObjectSerializerFault(FaultCode code, FaultReason reason, object detail, XmlObjectSerializer serialize
 399        {
 400            _code = code;
 401            _reason = reason;
 402            _detail = detail;
 403            _serializer = serializer;
 404            _actor = actor;
 405            _node = node;
 406        }
 407
 408        public override string Actor
 409        {
 410            get
 411            {
 412                return _actor;
 413            }
 414        }
 415
 416        public override FaultCode Code
 417        {
 418            get
 419            {
 420                return _code;
 421            }
 422        }
 423
 424        public override bool HasDetail
 425        {
 426            get
 427            {
 428                return _serializer != null;
 429            }
 430        }
 431
 432        public override string Node
 433        {
 434            get
 435            {
 436                return _node;
 437            }
 438        }
 439
 440        public override FaultReason Reason
 441        {
 442            get
 443            {
 444                return _reason;
 445            }
 446        }
 447
 448        private object ThisLock
 449        {
 450            get
 451            {
 452                return _code;
 453            }
 454        }
 455
 456        protected override void OnWriteDetailContents(XmlDictionaryWriter writer)
 457        {
 458            if (_serializer != null)
 459            {
 460                lock (ThisLock)
 461                {
 462                    _serializer.WriteObject(writer, _detail);
 463                }
 464            }
 465        }
 466    }
 467
 468    internal class ReceivedFault : MessageFault
 469    {
 470        private readonly FaultCode _code;
 471        private readonly FaultReason _reason;
 472        private readonly string _actor;
 473        private readonly string _node;
 474        private readonly XmlBuffer _detail;
 475        private readonly bool _hasDetail;
 476        private readonly EnvelopeVersion _receivedVersion;
 477
 478        private ReceivedFault(FaultCode code, FaultReason reason, string actor, string node, XmlBuffer detail, EnvelopeV
 479        {
 480            _code = code;
 481            _reason = reason;
 482            _actor = actor;
 483            _node = node;
 484            _receivedVersion = version;
 485            _hasDetail = InferHasDetail(detail);
 486            _detail = _hasDetail ? detail : null;
 487        }
 488
 489        public override string Actor
 490        {
 491            get
 492            {
 493                return _actor;
 494            }
 495        }
 496
 497        public override FaultCode Code
 498        {
 499            get
 500            {
 501                return _code;
 502            }
 503        }
 504
 505        public override bool HasDetail
 506        {
 507            get
 508            {
 509                return _hasDetail;
 510            }
 511        }
 512
 513        public override string Node
 514        {
 515            get
 516            {
 517                return _node;
 518            }
 519        }
 520
 521        public override FaultReason Reason
 522        {
 523            get
 524            {
 525                return _reason;
 526            }
 527        }
 528
 529        private bool InferHasDetail(XmlBuffer detail)
 530        {
 531            bool hasDetail = false;
 532            if (detail != null)
 533            {
 534                XmlDictionaryReader reader = detail.GetReader(0);
 535                if (!reader.IsEmptyElement && reader.Read()) // check if the detail element contains data
 536                {
 537                    hasDetail = (reader.MoveToContent() != XmlNodeType.EndElement);
 538                }
 539
 540                reader.Dispose();
 541            }
 542            return hasDetail;
 543        }
 544
 545        protected override void OnWriteDetail(XmlDictionaryWriter writer, EnvelopeVersion version)
 546        {
 547            using (XmlReader r = _detail.GetReader(0))
 548            {
 549                // Start the element
 550                base.OnWriteStartDetail(writer, version);
 551
 552                // Copy the attributes
 553                while (r.MoveToNextAttribute())
 554                {
 555                    if (ShouldWriteDetailAttribute(version, r.Prefix, r.LocalName, r.Value))
 556                    {
 557                        writer.WriteAttributeString(r.Prefix, r.LocalName, r.NamespaceURI, r.Value);
 558                    }
 559                }
 560                r.MoveToElement();
 561
 562                r.Read();
 563
 564                // Copy the contents
 565                while (r.NodeType != XmlNodeType.EndElement)
 566                {
 567                    writer.WriteNode(r, false);
 568                }
 569
 570                // End the element
 571                writer.WriteEndElement();
 572            }
 573        }
 574
 575        protected override void OnWriteStartDetail(XmlDictionaryWriter writer, EnvelopeVersion version)
 576        {
 577            using (XmlReader r = _detail.GetReader(0))
 578            {
 579                // Start the element
 580                base.OnWriteStartDetail(writer, version);
 581
 582                // Copy the attributes
 583                while (r.MoveToNextAttribute())
 584                {
 585                    if (ShouldWriteDetailAttribute(version, r.Prefix, r.LocalName, r.Value))
 586                    {
 587                        writer.WriteAttributeString(r.Prefix, r.LocalName, r.NamespaceURI, r.Value);
 588                    }
 589                }
 590            }
 591        }
 592
 593        protected override void OnWriteDetailContents(XmlDictionaryWriter writer)
 594        {
 595            using (XmlReader r = _detail.GetReader(0))
 596            {
 597                r.Read();
 598                while (r.NodeType != XmlNodeType.EndElement)
 599                {
 600                    writer.WriteNode(r, false);
 601                }
 602            }
 603        }
 604
 605        protected override XmlDictionaryReader OnGetReaderAtDetailContents()
 606        {
 607            XmlDictionaryReader reader = _detail.GetReader(0);
 608            reader.Read(); // Skip the detail element
 609            return reader;
 610        }
 611
 612        private bool ShouldWriteDetailAttribute(EnvelopeVersion targetVersion, string prefix, string localName, string a
 613        {
 614            // Handle fault detail version conversion from Soap12 to Soap11 -- scope tightly to only conversion from Soa
 615            // SOAP 1.1 specifications allow an arbitrary element within <fault>, hence:
 616            // transform this IFF the SOAP namespace specified will affect the namespace of the <detail> element,
 617            // AND the namespace specified is exactly the Soap12 Namespace.
 618            bool shouldSkip = _receivedVersion == EnvelopeVersion.Soap12    // original incoming version
 619                                && targetVersion == EnvelopeVersion.Soap11      // version to serialize to
 620                                && string.IsNullOrEmpty(prefix)                 // attribute prefix
 621                                && localName == "xmlns"                         // only transform namespace attributes, 
 622                                && attributeValue == XD.Message12Dictionary.Namespace.Value;
 623
 624            return !shouldSkip;
 625        }
 626
 627        public static ReceivedFault CreateFaultNone(XmlDictionaryReader reader, int maxBufferSize)
 628        {
 629            return CreateFault12Driver(reader, maxBufferSize, EnvelopeVersion.None);
 630        }
 631
 632        private static ReceivedFault CreateFault12Driver(XmlDictionaryReader reader, int maxBufferSize, EnvelopeVersion 
 633        {
 634            reader.ReadStartElement(XD.MessageDictionary.Fault, version.DictionaryNamespace);
 635            reader.ReadStartElement(XD.Message12Dictionary.FaultCode, version.DictionaryNamespace);
 636            FaultCode code = ReadFaultCode12Driver(reader, version);
 637            reader.ReadEndElement();
 638            List<FaultReasonText> translations = new List<FaultReasonText>();
 639            if (reader.IsEmptyElement)
 640            {
 641                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.AtLeastOneFaultReasonMu
 642            }
 643            else
 644            {
 645                reader.ReadStartElement(XD.Message12Dictionary.FaultReason, version.DictionaryNamespace);
 646                while (reader.IsStartElement(XD.Message12Dictionary.FaultText, version.DictionaryNamespace))
 647                {
 648                    translations.Add(ReadTranslation12(reader));
 649                }
 650
 651                reader.ReadEndElement();
 652            }
 653
 654            string actor = "";
 655            string node = "";
 656            if (reader.IsStartElement(XD.Message12Dictionary.FaultNode, version.DictionaryNamespace))
 657            {
 658                node = reader.ReadElementContentAsString();
 659            }
 660
 661            if (reader.IsStartElement(XD.Message12Dictionary.FaultRole, version.DictionaryNamespace))
 662            {
 663                actor = reader.ReadElementContentAsString();
 664            }
 665
 666            XmlBuffer detail = null;
 667            if (reader.IsStartElement(XD.Message12Dictionary.FaultDetail, version.DictionaryNamespace))
 668            {
 669                detail = new XmlBuffer(maxBufferSize);
 670                XmlDictionaryWriter writer = detail.OpenSection(reader.Quotas);
 671                writer.WriteNode(reader, false);
 672                detail.CloseSection();
 673                detail.Close();
 674            }
 675            reader.ReadEndElement();
 676            FaultReason reason = new FaultReason(translations);
 677            return new ReceivedFault(code, reason, actor, node, detail, version);
 678        }
 679
 680        private static FaultCode ReadFaultCode12Driver(XmlDictionaryReader reader, EnvelopeVersion version)
 681        {
 682            reader.ReadStartElement(XD.Message12Dictionary.FaultValue, version.DictionaryNamespace);
 683            XmlUtil.ReadContentAsQName(reader, out string localName, out string ns);
 684            reader.ReadEndElement();
 685            if (reader.IsStartElement(XD.Message12Dictionary.FaultSubcode, version.DictionaryNamespace))
 686            {
 687                reader.ReadStartElement();
 688                FaultCode subCode = ReadFaultCode12Driver(reader, version);
 689                reader.ReadEndElement();
 690                return new FaultCode(localName, ns, subCode);
 691            }
 692            return new FaultCode(localName, ns);
 693        }
 694
 695        public static ReceivedFault CreateFault12(XmlDictionaryReader reader, int maxBufferSize)
 696        {
 697            return CreateFault12Driver(reader, maxBufferSize, EnvelopeVersion.Soap12);
 698        }
 699
 700        private static FaultReasonText ReadTranslation12(XmlDictionaryReader reader)
 701        {
 702            string xmlLang = XmlUtil.GetXmlLangAttribute(reader);
 703            string text = reader.ReadElementContentAsString();
 704            return new FaultReasonText(text, xmlLang);
 705        }
 706
 707        public static ReceivedFault CreateFault11(XmlDictionaryReader reader, int maxBufferSize)
 708        {
 709            reader.ReadStartElement(XD.MessageDictionary.Fault, XD.Message11Dictionary.Namespace);
 710            reader.ReadStartElement(XD.Message11Dictionary.FaultCode, XD.Message11Dictionary.FaultNamespace);
 711            XmlUtil.ReadContentAsQName(reader, out string name, out string ns);
 712            FaultCode code = new FaultCode(name, ns);
 713            reader.ReadEndElement();
 714
 715            string xmlLang = reader.XmlLang;
 716            reader.MoveToContent();  // Don't do IsStartElement.  FaultString is required, so let the reader throw.
 717            string text = reader.ReadElementContentAsString(XD.Message11Dictionary.FaultString.Value, XD.Message11Dictio
 718            FaultReasonText translation = new FaultReasonText(text, xmlLang);
 719
 720            string actor = "";
 721            if (reader.IsStartElement(XD.Message11Dictionary.FaultActor, XD.Message11Dictionary.FaultNamespace))
 722            {
 723                actor = reader.ReadElementContentAsString();
 724            }
 725
 726            XmlBuffer detail = null;
 727            if (reader.IsStartElement(XD.Message11Dictionary.FaultDetail, XD.Message11Dictionary.FaultNamespace))
 728            {
 729                detail = new XmlBuffer(maxBufferSize);
 730                XmlDictionaryWriter writer = detail.OpenSection(reader.Quotas);
 731                writer.WriteNode(reader, false);
 732                detail.CloseSection();
 733                detail.Close();
 734            }
 735            reader.ReadEndElement();
 736            FaultReason reason = new FaultReason(translation);
 737            return new ReceivedFault(code, reason, actor, actor, detail, EnvelopeVersion.Soap11);
 738        }
 739    }
 740}