diff --git a/Aspects/Diagnostics/ClassMetadataRegistrar.cs b/Aspects/Diagnostics/ClassMetadataRegistrar.cs index 36310df..38f5af7 100644 --- a/Aspects/Diagnostics/ClassMetadataRegistrar.cs +++ b/Aspects/Diagnostics/ClassMetadataRegistrar.cs @@ -4,6 +4,7 @@ //using System.Data; //using System.Data.Metadata.Edm; //using System.Data.SqlClient; +//using System.Net; using System.Globalization; using System.Linq.Expressions; using System.Security; @@ -50,6 +51,7 @@ public static ClassMetadataRegistrar RegisterMetadata() //.Register() //.Register() //.Register() + //.Register() ; } diff --git a/Aspects/Diagnostics/DumpAttribute.cs b/Aspects/Diagnostics/DumpAttribute.cs index f6ba1ad..9b67eca 100644 --- a/Aspects/Diagnostics/DumpAttribute.cs +++ b/Aspects/Diagnostics/DumpAttribute.cs @@ -35,12 +35,12 @@ public enum ShouldDump /// instance itself - e.g. from a property containing the instance or explicitly passed to the . In these /// cases not null class applicable properties from the instance attribute take precedence over the class attribute properties. /// - [SuppressMessage("Microsoft.Design", "CA1019:DefineAccessorsForAttributeArguments", Justification="The display positional parameter is equal to Skip named parameter.")] + [SuppressMessage("Microsoft.Design", "CA1019:DefineAccessorsForAttributeArguments", Justification = "The display positional parameter is equal to Skip named parameter.")] [AttributeUsage( AttributeTargets.Struct| AttributeTargets.Class | AttributeTargets.Field | - AttributeTargets.Property, AllowMultiple=false, Inherited=false)] + AttributeTargets.Property, AllowMultiple = false, Inherited = false)] public sealed class DumpAttribute : Attribute, IEquatable, ICloneable { #region Constant instances. @@ -267,7 +267,7 @@ public string ValueFormat /// Gets or sets the name of the dump method in the class specified by . The dump method implements custom formatting of the property's value. /// The method must be static, public, have a return type of and must take a single parameter of type or a base type of the property. /// If the is not specified then the will look for a parameterless instance method by the same name in the - /// property's class or a static method with parameter the type or a base type of the property. + /// property's class or a static method with parameter the type or a base type of the property in the property's class, base class or the metadata class. /// /// /// Applicable to properties only. @@ -392,8 +392,8 @@ public override int GetHashCode() /// true if the objects are considered to be equal (); /// otherwise false. /// - public static bool operator==(DumpAttribute left, DumpAttribute right) => ReferenceEquals(left, null) - ? ReferenceEquals(right, null) + public static bool operator ==(DumpAttribute left, DumpAttribute right) => ReferenceEquals(left, null) + ? ReferenceEquals(right, null) : left.Equals(right); /// @@ -405,7 +405,7 @@ public override int GetHashCode() /// true if the objects are not considered to be equal (); /// otherwise false. /// - public static bool operator!=(DumpAttribute left, DumpAttribute right) => !(left==right); + public static bool operator !=(DumpAttribute left, DumpAttribute right) => !(left==right); #endregion } } diff --git a/Aspects/Diagnostics/ExternalMetadata/WebExceptionDumpMetadata.cs b/Aspects/Diagnostics/ExternalMetadata/WebExceptionDumpMetadata.cs new file mode 100644 index 0000000..5755e88 --- /dev/null +++ b/Aspects/Diagnostics/ExternalMetadata/WebExceptionDumpMetadata.cs @@ -0,0 +1,42 @@ +using System; +using System.IO; +using System.Net; + +namespace vm.Aspects.Diagnostics.ExternalMetadata +{ + /// + public abstract class WebExceptionDumpMetadata + { + /// + [Dump(0)] + public object Status; + + /// + [Dump(1, DumpClass = typeof(WebExceptionDumpMetadata), DumpMethod = nameof(DumpResponse))] + public object Response; + + /// + public static string DumpResponse( + WebResponse response) + { + var stream = response?.GetResponseStream(); + + if (stream == null) + return ""; + + try + { + var reader = new StreamReader(stream, true); + + var result = reader.ReadToEnd(); + stream.Seek(0, SeekOrigin.Begin); + + return result; + } + catch (Exception) + { + return ""; + } + } + } +} diff --git a/Aspects/Diagnostics/NuGet/ObjectDumper.nuspec b/Aspects/Diagnostics/NuGet/ObjectDumper.nuspec index 67faf9d..6abdd3f 100644 --- a/Aspects/Diagnostics/NuGet/ObjectDumper.nuspec +++ b/Aspects/Diagnostics/NuGet/ObjectDumper.nuspec @@ -2,7 +2,7 @@ AspectObjectDumper - 1.5.3 + 1.5.4 Val Melamed Val Melamed @@ -28,7 +28,7 @@ * Build and tested with .NET 4.0, 4.6. This package targets .NET 4.0. - Added contracts to the internal DumpTextWriter. + Now the dumper searches for the DumpAttribute.DumpMethod also in the class' DumpAttribute. https://aspectobjectdumper.codeplex.com/license https://aspectobjectdumper.codeplex.com/ diff --git a/Aspects/Diagnostics/NuGet/PublishObjectDumper.cmd b/Aspects/Diagnostics/NuGet/PublishObjectDumper.cmd index 62a2e1b..44c698c 100644 --- a/Aspects/Diagnostics/NuGet/PublishObjectDumper.cmd +++ b/Aspects/Diagnostics/NuGet/PublishObjectDumper.cmd @@ -1,6 +1,6 @@ pushd cd %~dp0.. -del ..\*.nupkg +del *.nupkg NuGet Update -self call "%VS140COMNTOOLS%vsvars32.bat" if not .%1.==.. NuGet SetApiKey %1 @@ -8,9 +8,10 @@ msbuild vm.Aspects.Diagnostics.ObjectDumper.csproj /t:Rebuild /p:Configuration=R if errorlevel 1 goto exit NuGet Pack NuGet\ObjectDumper.nuspec -Prop Configuration=Release -symbols if errorlevel 1 goto exit -@echo Press any key to push to NuGet... > con: +if exist c:\NuGet copy /y *.nupkg c:\NuGet +@echo Press any key to push to NuGet.org... > con: @pause > nul: -NuGet Push AspectObjectDumper.1.5.3.nupkg +NuGet Push AspectObjectDumper.1.5.4.nupkg :exit popd pause \ No newline at end of file diff --git a/Aspects/Diagnostics/ObjectTextDumper.cs b/Aspects/Diagnostics/ObjectTextDumper.cs index c73d67e..eaf70b0 100644 --- a/Aspects/Diagnostics/ObjectTextDumper.cs +++ b/Aspects/Diagnostics/ObjectTextDumper.cs @@ -84,7 +84,7 @@ public sealed partial class ObjectTextDumper : IDisposable /// /// The default binding flags determining which properties to be dumped /// - [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId="Flags")] + [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Flags")] public static BindingFlags DefaultPropertiesBindingFlags { get { return defaultPropertiesBindingFlags; } @@ -96,7 +96,7 @@ public static BindingFlags DefaultPropertiesBindingFlags /// /// The default binding flags determining which fields to be dumped /// - [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId="Flags")] + [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Flags")] public static BindingFlags DefaultFieldsBindingFlags { get { return defaultFieldsBindingFlags; } @@ -115,8 +115,8 @@ public static BindingFlags DefaultFieldsBindingFlags /// The binding flags of the properties. /// The binding flags of the fields. /// Thrown if is null. - [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId="Flags")] - [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId="0")] + [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Flags")] + [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")] public ObjectTextDumper( TextWriter writer, int indentLevel = 0, @@ -471,7 +471,7 @@ void DumpProperty( Contract.Requires(state!=null); // should we dump it at all? - if (!state.CurrentProperty.CanRead() || + if (!state.CurrentProperty.CanRead() || state.CurrentPropertyDumpAttribute.Skip == ShouldDump.Skip) return; @@ -504,7 +504,7 @@ void DumpProperty( try { - value = pi != null + value = pi != null ? pi.GetValue(state.Instance, null) : fi.GetValue(state.Instance); } @@ -515,7 +515,7 @@ void DumpProperty( } // should we dump a null value of the current property - if (value == null && + if (value == null && (state.CurrentPropertyDumpAttribute.DumpNullValues==ShouldDump.Skip || state.CurrentPropertyDumpAttribute.DumpNullValues==ShouldDump.Default && state.DumpNullValues==ShouldDump.Skip)) return; @@ -554,12 +554,12 @@ void DumpProperty( DumpObjectOfNonBasicValue( value, null, - state.CurrentPropertyDumpAttribute.IsDefaultAttribute() + state.CurrentPropertyDumpAttribute.IsDefaultAttribute() ? null : state.CurrentPropertyDumpAttribute); } - [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification="It's OK.")] + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "It's OK.")] bool DumpedPropertyCustom( DumpState state, object value, @@ -585,17 +585,17 @@ bool DumpedPropertyCustom( return false; if (string.IsNullOrWhiteSpace(dumpMethodName)) - dumpMethodName = nameof(Dump); + dumpMethodName = "Dump"; MethodInfo dumpMethod = null; // best match MethodInfo dumpMethod2 = null; // second best - // try external class if specified + // try the external class if specified if (dumpClass != null) { foreach (var mi in dumpClass.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy) - .Where(mi => mi.Name == dumpMethodName && - mi.ReturnType == typeof(string) && + .Where(mi => mi.Name == dumpMethodName && + mi.ReturnType == typeof(string) && mi.GetParameters().Count() == 1)) { if (mi.GetParameters()[0].ParameterType == type) @@ -622,14 +622,18 @@ bool DumpedPropertyCustom( return true; } - // try the property's class or base class + // try the property's class or base class, or metadata class foreach (var mi in type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy) - .Where(mi => mi.Name == dumpMethodName && + .Where(mi => mi.Name == dumpMethodName && mi.ReturnType == typeof(string)) - .Union(type.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy) - .Where(mi => mi.Name == dumpMethodName && - mi.ReturnType == typeof(string) && - mi.GetParameters().Count() == 1))) + .Union(type.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy) + .Where(mi => mi.Name == dumpMethodName && + mi.ReturnType == typeof(string) && + mi.GetParameters().Count() == 1)) + .Union(state.ClassDumpData.Metadata.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy) + .Where(mi => mi.Name == dumpMethodName && + mi.ReturnType == typeof(string) && + mi.GetParameters().Count() == 1))) { // found an instance method if (!mi.IsStatic && mi.GetParameters().Count() == 0) @@ -644,7 +648,7 @@ bool DumpedPropertyCustom( dumpMethod = mi; else if (mi.GetParameters()[0].ParameterType.IsAssignableFrom(type)) - dumpMethod2 = mi; + dumpMethod2 = mi; } } @@ -746,8 +750,8 @@ bool DumpedDelegate(object value) d.Method.DeclaringType!=null ? d.Method.DeclaringType.Namespace : string.Empty, d.Method.DeclaringType!=null ? d.Method.DeclaringType.AssemblyQualifiedName : string.Empty, d.Method.Name, - d.Target==null - ? Resources.ClassMethodDesignator + d.Target==null + ? Resources.ClassMethodDesignator : Resources.InstanceMethodDesignator); return true; @@ -810,7 +814,7 @@ bool DumpedSequenceObject( max = int.MaxValue; else if (max == 0) // limit sequences of primitive types (can be very big) - max = DumpAttribute.DefaultMaxElements; + max = DumpAttribute.DefaultMaxElements; if (sequenceType == typeof(byte[])) { @@ -895,7 +899,7 @@ static string GetTypeName( string typeName = type.Name; - if (typeName.Length > 65 && + if (typeName.Length > 65 && _hexadecimalSuffix.IsMatch(typeName.Substring(typeName.Length - 65-1))) typeName = type.BaseType.Name.Substring(0, typeName.Length-65); @@ -945,7 +949,7 @@ static string GetTypeName( /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// /// Invokes the protected virtual . - [SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification="It is correct.")] + [SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification = "It is correct.")] public void Dispose() { // if it is disposed or in a process of disposing - return. diff --git a/Aspects/Diagnostics/Properties/AssemblyInfo.cs b/Aspects/Diagnostics/Properties/AssemblyInfo.cs index 89e47ff..2736f76 100644 --- a/Aspects/Diagnostics/Properties/AssemblyInfo.cs +++ b/Aspects/Diagnostics/Properties/AssemblyInfo.cs @@ -2,9 +2,9 @@ [assembly: AssemblyTitle("vm.Aspects.Diagnostics.ObjectDumper")] [assembly: AssemblyDescription("Dumps the properties' and fields' values of any .NET object in a text form.")] -[assembly: AssemblyVersion("1.5.3")] -[assembly: AssemblyFileVersion("1.5.3")] -[assembly: AssemblyInformationalVersion("1.5.3")] +[assembly: AssemblyVersion("1.5.4")] +[assembly: AssemblyFileVersion("1.5.4")] +[assembly: AssemblyInformationalVersion("1.5.4")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo( "vm.Aspects.Diagnostics.ObjectDumper.Tests, " + diff --git a/Aspects/Diagnostics/vm.Aspects.Diagnostics.ObjectDumper.csproj b/Aspects/Diagnostics/vm.Aspects.Diagnostics.ObjectDumper.csproj index 9253ae7..8561eda 100644 --- a/Aspects/Diagnostics/vm.Aspects.Diagnostics.ObjectDumper.csproj +++ b/Aspects/Diagnostics/vm.Aspects.Diagnostics.ObjectDumper.csproj @@ -229,6 +229,7 @@ + diff --git a/Aspects/Linq/Expressions/Serialization/NuGet/ExpressionSerialization.nuspec b/Aspects/Linq/Expressions/Serialization/NuGet/ExpressionSerialization.nuspec index 7ab8e35..4250d52 100644 --- a/Aspects/Linq/Expressions/Serialization/NuGet/ExpressionSerialization.nuspec +++ b/Aspects/Linq/Expressions/Serialization/NuGet/ExpressionSerialization.nuspec @@ -2,7 +2,7 @@ AspectExpressionSerialization - 1.0.46 + 1.0.48 Val Melamed Val Melamed diff --git a/Aspects/Linq/Expressions/Serialization/Properties/AssemblyInfo.cs b/Aspects/Linq/Expressions/Serialization/Properties/AssemblyInfo.cs index fff31c3..66300ed 100644 --- a/Aspects/Linq/Expressions/Serialization/Properties/AssemblyInfo.cs +++ b/Aspects/Linq/Expressions/Serialization/Properties/AssemblyInfo.cs @@ -4,9 +4,9 @@ [assembly: AssemblyTitle("vm.Aspects.Linq.Expressions.Serialization")] [assembly: AssemblyDescription("Serializes and deserializes LINQ expression trees to and from XML documents.")] -[assembly: AssemblyVersion("1.0.46")] -[assembly: AssemblyFileVersion("1.0.46")] -[assembly: AssemblyInformationalVersion("1.0.46")] +[assembly: AssemblyVersion("1.0.48")] +[assembly: AssemblyFileVersion("1.0.48")] +[assembly: AssemblyInformationalVersion("1.0.48")] [assembly: InternalsVisibleTo( "vm.Aspects.Linq.Expressions.Serialization.Test, " + diff --git a/Aspects/Model/Properties/AssemblyInfo.cs b/Aspects/Model/Properties/AssemblyInfo.cs index 6f2956c..e6248b1 100644 --- a/Aspects/Model/Properties/AssemblyInfo.cs +++ b/Aspects/Model/Properties/AssemblyInfo.cs @@ -3,9 +3,9 @@ [assembly: AssemblyTitle("vm.Aspect.Model")] [assembly: AssemblyDescription("Defines the IRepository and related base classes and utilities - a framework of building domain object model.")] -[assembly: AssemblyVersion("1.0.46")] -[assembly: AssemblyFileVersion("1.0.46")] -[assembly: AssemblyInformationalVersion("1.0.46")] +[assembly: AssemblyVersion("1.0.48")] +[assembly: AssemblyFileVersion("1.0.48")] +[assembly: AssemblyInformationalVersion("1.0.48")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo( "vm.Aspects.Model.Tests, " + diff --git a/Aspects/Model/Tests/packages.config b/Aspects/Model/Tests/packages.config index 6a01294..313456b 100644 --- a/Aspects/Model/Tests/packages.config +++ b/Aspects/Model/Tests/packages.config @@ -1,6 +1,6 @@  - + diff --git a/Aspects/Model/packages.config b/Aspects/Model/packages.config index 9567c9c..017755b 100644 --- a/Aspects/Model/packages.config +++ b/Aspects/Model/packages.config @@ -1,6 +1,6 @@  - + diff --git a/Aspects/NuGet/PublishAspects.cmd b/Aspects/NuGet/PublishAspects.cmd index e38972e..d03afcc 100644 --- a/Aspects/NuGet/PublishAspects.cmd +++ b/Aspects/NuGet/PublishAspects.cmd @@ -15,9 +15,10 @@ if errorlevel 1 goto exit cd .. NuGet Pack NuGet\vm.Aspects.nuspec -symbols -Prop Configuration=Release if errorlevel 1 goto exit -@echo Press any key to push to NuGet... > con: +if exist c:\NuGet copy /y *.nupkg c:\NuGet +@echo Press any key to push to NuGet.org... > con: @pause > nul: -NuGet Push vm.Aspects.1.0.46-beta.nupkg +NuGet Push vm.Aspects.1.0.48-beta.nupkg :exit popd pause \ No newline at end of file diff --git a/Aspects/NuGet/vm.Aspects.nuspec b/Aspects/NuGet/vm.Aspects.nuspec index 22abc51..d3f95a1 100644 --- a/Aspects/NuGet/vm.Aspects.nuspec +++ b/Aspects/NuGet/vm.Aspects.nuspec @@ -2,7 +2,7 @@ vm.Aspects - 1.0.46-beta + 1.0.48-beta Val Melamed Val Melamed diff --git a/Aspects/Parsers/Properties/AssemblyInfo.cs b/Aspects/Parsers/Properties/AssemblyInfo.cs index 6cdbc77..8d75cbe 100644 --- a/Aspects/Parsers/Properties/AssemblyInfo.cs +++ b/Aspects/Parsers/Properties/AssemblyInfo.cs @@ -6,9 +6,9 @@ [assembly: AssemblyTitle("vm.Aspects.Parser")] [assembly: AssemblyDescription("Text parsing readers, e.g. CSV/TSV reader.")] -[assembly: AssemblyVersion("1.0.46")] -[assembly: AssemblyFileVersion("1.0.46")] -[assembly: AssemblyInformationalVersion("1.0.46")] +[assembly: AssemblyVersion("1.0.48")] +[assembly: AssemblyFileVersion("1.0.48")] +[assembly: AssemblyInformationalVersion("1.0.48")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo( "vm.Aspects.Parsers.Tests, " + diff --git a/Aspects/Properties/AssemblyInfo.cs b/Aspects/Properties/AssemblyInfo.cs index 088108f..ea5d8ef 100644 --- a/Aspects/Properties/AssemblyInfo.cs +++ b/Aspects/Properties/AssemblyInfo.cs @@ -2,9 +2,9 @@ [assembly: AssemblyTitle("vm.Aspects")] [assembly: AssemblyDescription("A set of classes addressing various common cross-cutting concerns.")] -[assembly: AssemblyVersion("1.0.46")] -[assembly: AssemblyFileVersion("1.0.46")] -[assembly: AssemblyInformationalVersion("1.0.46")] +[assembly: AssemblyVersion("1.0.48")] +[assembly: AssemblyFileVersion("1.0.48")] +[assembly: AssemblyInformationalVersion("1.0.48")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo( "vm.Aspects.Test, " + diff --git a/Aspects/Security/Cryptography/Ciphers/NuGet/PublishCiphers.cmd b/Aspects/Security/Cryptography/Ciphers/NuGet/PublishCiphers.cmd index 393d6cf..09df3df 100644 --- a/Aspects/Security/Cryptography/Ciphers/NuGet/PublishCiphers.cmd +++ b/Aspects/Security/Cryptography/Ciphers/NuGet/PublishCiphers.cmd @@ -14,7 +14,8 @@ msbuild MacKey\MacKey.csproj /t:Rebuild /p:Configuration=Release /p:TargetFramew if errorlevel 1 goto exit NuGet Pack NuGet\Ciphers.nuspec -Prop Configuration=Release -symbols if errorlevel 1 goto exit -@echo Press any key to push to NuGet... > con: +if exist c:\NuGet copy /y *.nupkg c:\NuGet +@echo Press any key to push to NuGet.org... > con: @pause > nul: NuGet Push Ciphers.1.11.8.nupkg :exit diff --git a/Aspects/Test/packages.config b/Aspects/Test/packages.config index 8bb4a7b..cb99d2f 100644 --- a/Aspects/Test/packages.config +++ b/Aspects/Test/packages.config @@ -1,6 +1,6 @@  - + diff --git a/Aspects/Wcf/Behaviors/PreflightOperationBehavior.cs b/Aspects/Wcf/Behaviors/PreflightOperationBehavior.cs index 0b1f77b..df920b8 100644 --- a/Aspects/Wcf/Behaviors/PreflightOperationBehavior.cs +++ b/Aspects/Wcf/Behaviors/PreflightOperationBehavior.cs @@ -37,5 +37,7 @@ public void ApplyDispatchBehavior( public void Validate(OperationDescription operationDescription) { } + + internal string AllowedMethods => string.Join(", ", _allowedMethods); } } diff --git a/Aspects/Wcf/FaultContracts/ProtocolExceptionToWebFaultResolver.cs b/Aspects/Wcf/FaultContracts/ProtocolExceptionToWebFaultResolver.cs index 726b95b..75f96ab 100644 --- a/Aspects/Wcf/FaultContracts/ProtocolExceptionToWebFaultResolver.cs +++ b/Aspects/Wcf/FaultContracts/ProtocolExceptionToWebFaultResolver.cs @@ -18,7 +18,7 @@ namespace vm.Aspects.Wcf.FaultContracts /// public static class ProtocolExceptionToWebFaultResolver { - const string _rexFaultType = @",\s*""faultType""\s*:\s*""(?[^""]+)"","; + const string _rexFaultType = @"\s*""faultType""\s*:\s*""(?[^""]+)"""; static Lazy _faultType = new Lazy(() => new Regex(_rexFaultType, RegexOptions.Compiled)); @@ -40,14 +40,37 @@ public static Fault Resolve( serializedFault = null; + var wx = exception.InnerException as WebException; + + if (wx == null) + return null; + + return Resolve(wx, out serializedFault); + } + + /// + /// Resolves web exceptions to -s. + /// + /// The exception to resolve. + /// The serialized fault string contained in the . + /// The resolved instance or . + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Here we handle the specific exception.")] + [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Justification = "We need two results here.")] + public static Fault Resolve( + WebException exception, + out string serializedFault) + { + Contract.Requires(exception != null, nameof(exception)); + + serializedFault = null; + try { - var wx = exception.InnerException as WebException; + var stream = exception.Response?.GetResponseStream(); - if (wx == null) + if (stream == null) return null; - var stream = wx.Response.GetResponseStream(); var reader = new StreamReader(stream, true); serializedFault = reader.ReadToEnd(); diff --git a/Aspects/Wcf/Properties/AssemblyInfo.cs b/Aspects/Wcf/Properties/AssemblyInfo.cs index 91b3684..6be2569 100644 --- a/Aspects/Wcf/Properties/AssemblyInfo.cs +++ b/Aspects/Wcf/Properties/AssemblyInfo.cs @@ -3,9 +3,9 @@ [assembly: AssemblyTitle("Wcf")] [assembly: AssemblyDescription("A set of classes and generics simplifying the initial configuration work of creating WCF services.")] -[assembly: AssemblyVersion("1.0.46")] -[assembly: AssemblyFileVersion("1.0.46")] -[assembly: AssemblyInformationalVersion("1.0.46")] +[assembly: AssemblyVersion("1.0.48")] +[assembly: AssemblyFileVersion("1.0.48")] +[assembly: AssemblyInformationalVersion("1.0.48")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo( "vm.Aspects.Wcf.Test, " + diff --git a/Aspects/Wcf/Services/ServiceHostExtensions.cs b/Aspects/Wcf/Services/ServiceHostExtensions.cs index f9dc59f..345f4bf 100644 --- a/Aspects/Wcf/Services/ServiceHostExtensions.cs +++ b/Aspects/Wcf/Services/ServiceHostExtensions.cs @@ -3,7 +3,9 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; +using System.Globalization; using System.Linq; +using System.Reflection; using System.Security.Cryptography.X509Certificates; using System.ServiceModel; using System.ServiceModel.Channels; @@ -424,6 +426,11 @@ static void AddPreflightOperationSelectors( { Contract.Requires(operations != null, nameof(operations)); + if (!operations.Any()) + return; + + Trace.WriteLine(string.Format(CultureInfo.InvariantCulture, "Generating OPTIONS handlers for {0}.", operations.First().DeclaringContract.ContractType.FullName)); + var uriTemplates = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (var operation in operations) @@ -434,16 +441,15 @@ static void AddPreflightOperationSelectors( string originalUriTemplate; string originalMethod; + MethodInfo method = operation.SyncMethod ?? operation.TaskMethod ?? operation.BeginMethod; var webInvoke = operation.Behaviors.Find(); if (webInvoke != null) { - originalMethod = webInvoke.Method != null - ? webInvoke.Method - : "POST"; - if (originalMethod == "OPTIONS") + if (webInvoke.Method == "OPTIONS") continue; + originalMethod = webInvoke.Method != null ? webInvoke.Method : "POST"; originalUriTemplate = webInvoke.UriTemplate != null ? NormalizeTemplate(webInvoke.UriTemplate) : operation.Name; @@ -463,11 +469,14 @@ static void AddPreflightOperationSelectors( continue; } + if (string.IsNullOrWhiteSpace(originalUriTemplate)) + originalUriTemplate = "/"; + PreflightOperationBehavior preflightOperationBehavior; if (uriTemplates.TryGetValue(originalUriTemplate, out preflightOperationBehavior)) { - // there is already an OPTIONS operation for this URI, we can reuse it + // there is already an OPTIONS operation for this URI, we can reuse it, just add the method preflightOperationBehavior.AddAllowedMethod(originalMethod); continue; } diff --git a/Aspects/Wcf/packages.config b/Aspects/Wcf/packages.config index f8e173d..ec312dd 100644 --- a/Aspects/Wcf/packages.config +++ b/Aspects/Wcf/packages.config @@ -1,6 +1,6 @@  - + diff --git a/Aspects/packages.config b/Aspects/packages.config index 762e807..87614a0 100644 --- a/Aspects/packages.config +++ b/Aspects/packages.config @@ -1,6 +1,6 @@  - +