From 67b43b4cfe965607d364bda80a3b1bf222a081cf Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Mon, 28 Sep 2015 08:15:11 -0700 Subject: [PATCH] Workaround Mono bugs to fix travis This change works around two mono issues that are blocking travis. I'd like to have tests skip instead, but unfortunately that would mean not running any validation tests on mono so this seems better. - RuntimeHelpers.GetHashCode will sometimes crash the runtime - PropertyHelper sometimes returns throws null-ref --- .../Validation/ValidationStateDictionary.cs | 10 ++++++ .../DefaultComplexObjectValidationStrategy.cs | 32 ++++++++++++++++++- .../Validation/ReferenceEqualityComparer.cs | 11 +++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.Mvc.Abstractions/ModelBinding/Validation/ValidationStateDictionary.cs b/src/Microsoft.AspNet.Mvc.Abstractions/ModelBinding/Validation/ValidationStateDictionary.cs index 1a227692d7..99e1012f4d 100644 --- a/src/Microsoft.AspNet.Mvc.Abstractions/ModelBinding/Validation/ValidationStateDictionary.cs +++ b/src/Microsoft.AspNet.Mvc.Abstractions/ModelBinding/Validation/ValidationStateDictionary.cs @@ -163,6 +163,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation private class ReferenceEqualityComparer : IEqualityComparer { + private static readonly bool IsMono = Type.GetType("Mono.Runtime") != null; + public static readonly ReferenceEqualityComparer Instance = new ReferenceEqualityComparer(); public new bool Equals(object x, object y) @@ -172,6 +174,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation public int GetHashCode(object obj) { + // RuntimeHelpers.GetHashCode sometimes crashes the runtime on Mono 4.0.4 + // See: https://github.com/aspnet/External/issues/45 + // The workaround here is to just not hash anything, and fall back to an equality check. + if (IsMono) + { + return 0; + } + return RuntimeHelpers.GetHashCode(obj); } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/Validation/DefaultComplexObjectValidationStrategy.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/Validation/DefaultComplexObjectValidationStrategy.cs index 1e7205deed..6afc3ccdb5 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/Validation/DefaultComplexObjectValidationStrategy.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/Validation/DefaultComplexObjectValidationStrategy.cs @@ -4,6 +4,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Reflection; namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { @@ -12,6 +13,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation /// public class DefaultComplexObjectValidationStrategy : IValidationStrategy { + private static readonly bool IsMono = Type.GetType("Mono.Runtime") != null; + /// /// Gets an instance of . /// @@ -78,7 +81,34 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation var property = _properties[_index]; var propertyName = property.BinderModelName ?? property.PropertyName; var key = ModelNames.CreatePropertyModelName(_key, propertyName); - var model = property.PropertyGetter(_model); + + object model; + + // Our property accessors don't work on Mono 4.0.4 - see https://github.com/aspnet/External/issues/44 + // This is a workaround for what the PropertyGetter does in the background. + if (IsMono) + { + if (_model == null) + { + model = null; + } + else + { + var propertyInfo = _model.GetType().GetRuntimeProperty(property.PropertyName); + try + { + model = propertyInfo.GetValue(_model); + } + catch (TargetInvocationException ex) + { + throw ex.InnerException; + } + } + } + else + { + model = property.PropertyGetter(_model); + } _entry = new ValidationEntry(property, key, model); diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/Validation/ReferenceEqualityComparer.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/Validation/ReferenceEqualityComparer.cs index e1ab5ba427..ea6c2e2224 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/Validation/ReferenceEqualityComparer.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/Validation/ReferenceEqualityComparer.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Generic; using System.Runtime.CompilerServices; @@ -10,6 +11,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { private static readonly ReferenceEqualityComparer _instance = new ReferenceEqualityComparer(); + private static readonly bool IsMono = Type.GetType("Mono.Runtime") != null; + public static ReferenceEqualityComparer Instance { get @@ -25,6 +28,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation public int GetHashCode(object obj) { + // RuntimeHelpers.GetHashCode sometimes crashes the runtime on Mono 4.0.4 + // See: https://github.com/aspnet/External/issues/45 + // The workaround here is to just not hash anything, and fall back to an equality check. + if (IsMono) + { + return 0; + } + return RuntimeHelpers.GetHashCode(obj); } }