Merge remote-tracking branch 'origin/6.2.0-membershipprovider' into 7.0.0
Conflicts: src/Umbraco.Tests/ObjectExtensionsTests.cs src/Umbraco.Web/WebBootManager.cs
This commit is contained in:
@@ -22,8 +22,8 @@ namespace Umbraco.Core
|
||||
if (value is string)
|
||||
{
|
||||
var str = (string)value;
|
||||
if (str == null || str.Length == 0 || str == "0") return false;
|
||||
if (str == "1") return true;
|
||||
if (str == "0" || str == "") return false;
|
||||
}
|
||||
|
||||
return base.ConvertFrom(context, culture, value);
|
||||
|
||||
@@ -16,7 +16,6 @@ namespace Umbraco.Core
|
||||
{
|
||||
public static class ObjectExtensions
|
||||
{
|
||||
|
||||
//private static readonly ConcurrentDictionary<Type, Func<object>> ObjectFactoryCache = new ConcurrentDictionary<Type, Func<object>>();
|
||||
|
||||
public static IEnumerable<T> AsEnumerableOfOne<T>(this T input)
|
||||
@@ -93,8 +92,30 @@ namespace Umbraco.Core
|
||||
//check for string so that overloaders of ToString() can take advantage of the conversion.
|
||||
if (destinationType == typeof(string)) return Attempt<object>.Succeed(input.ToString());
|
||||
|
||||
if (!destinationType.IsGenericType || destinationType.GetGenericTypeDefinition() != typeof(Nullable<>))
|
||||
// if we've got a nullable of something, we try to convert directly to that thing.
|
||||
if (destinationType.IsGenericType && destinationType.GetGenericTypeDefinition() == typeof(Nullable<>))
|
||||
{
|
||||
// recursively call into myself with the inner (not-nullable) type and handle the outcome
|
||||
var nonNullable = input.TryConvertTo(Nullable.GetUnderlyingType(destinationType));
|
||||
|
||||
// and if sucessful, fall on through to rewrap in a nullable; if failed, pass on the exception
|
||||
if (nonNullable.Success)
|
||||
input = nonNullable.Result; // now fall on through...
|
||||
else
|
||||
return Attempt<object>.Fail(nonNullable.Exception);
|
||||
}
|
||||
|
||||
// we've already dealed with nullables, so any other generic types need to fall through
|
||||
if (!destinationType.IsGenericType)
|
||||
{
|
||||
if (input is string)
|
||||
{
|
||||
var result = TryConvertToFromString(input as string, destinationType);
|
||||
|
||||
// if we processed the string (succeed or fail), we're done
|
||||
if (result.HasValue) return result.Value;
|
||||
}
|
||||
|
||||
//TODO: Do a check for destination type being IEnumerable<T> and source type implementing IEnumerable<T> with
|
||||
// the same 'T', then we'd have to find the extension method for the type AsEnumerable() and execute it.
|
||||
|
||||
@@ -158,7 +179,6 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (TypeHelper.IsTypeAssignableFrom<IConvertible>(input))
|
||||
{
|
||||
try
|
||||
@@ -175,6 +195,119 @@ namespace Umbraco.Core
|
||||
return Attempt<object>.Fail();
|
||||
}
|
||||
|
||||
private static Nullable<Attempt<object>> TryConvertToFromString(this string input, Type destinationType)
|
||||
{
|
||||
if (destinationType == typeof(string))
|
||||
return Attempt<object>.Succeed(input);
|
||||
|
||||
if (input == null || input.Length == 0)
|
||||
{
|
||||
if (destinationType == typeof(Boolean))
|
||||
return Attempt<object>.Succeed(false); // special case for booleans, null/empty == false
|
||||
else if (destinationType == typeof(DateTime))
|
||||
return Attempt<object>.Succeed(DateTime.MinValue);
|
||||
}
|
||||
|
||||
// we have a non-empty string, look for type conversions in the expected order of frequency of use...
|
||||
if (destinationType.IsPrimitive)
|
||||
{
|
||||
if (destinationType == typeof(Int32))
|
||||
{
|
||||
Int32 value;
|
||||
return Int32.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Int64))
|
||||
{
|
||||
Int64 value;
|
||||
return Int64.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Boolean))
|
||||
{
|
||||
Boolean value;
|
||||
if (Boolean.TryParse(input, out value))
|
||||
return Attempt<object>.Succeed(value); // don't declare failure so the CustomBooleanTypeConverter can try
|
||||
}
|
||||
else if (destinationType == typeof(Int16))
|
||||
{
|
||||
Int16 value;
|
||||
return Int16.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Double))
|
||||
{
|
||||
Double value;
|
||||
return Double.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Single))
|
||||
{
|
||||
Single value;
|
||||
return Single.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Char))
|
||||
{
|
||||
Char value;
|
||||
return Char.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Byte))
|
||||
{
|
||||
Byte value;
|
||||
return Byte.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(SByte))
|
||||
{
|
||||
SByte value;
|
||||
return SByte.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(UInt32))
|
||||
{
|
||||
UInt32 value;
|
||||
return UInt32.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(UInt16))
|
||||
{
|
||||
UInt16 value;
|
||||
return UInt16.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(UInt64))
|
||||
{
|
||||
UInt64 value;
|
||||
return UInt64.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
}
|
||||
else if (destinationType == typeof(Guid))
|
||||
{
|
||||
Guid value;
|
||||
return Guid.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(DateTime))
|
||||
{
|
||||
DateTime value;
|
||||
return DateTime.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(DateTimeOffset))
|
||||
{
|
||||
DateTimeOffset value;
|
||||
return DateTimeOffset.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(TimeSpan))
|
||||
{
|
||||
TimeSpan value;
|
||||
return TimeSpan.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Decimal))
|
||||
{
|
||||
Decimal value;
|
||||
return Decimal.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Version))
|
||||
{
|
||||
Version value;
|
||||
return Version.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
// E_NOTIMPL IPAddress, BigInteger
|
||||
|
||||
return null; // we can't decide...
|
||||
}
|
||||
|
||||
internal static void CheckThrowObjectDisposed(this IDisposable disposable, bool isDisposed, string objectname)
|
||||
{
|
||||
//TODO: Localise this exception
|
||||
@@ -296,7 +429,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
return "\"{0}\"".InvariantFormat(obj);
|
||||
}
|
||||
if (obj is int || obj is Int16 || obj is Int64 || obj is double || obj is bool || obj is int? || obj is Int16? || obj is Int64? || obj is double? || obj is bool?)
|
||||
if (obj is int || obj is Int16 || obj is Int64 || obj is float || obj is double || obj is bool || obj is int? || obj is Int16? || obj is Int64? || obj is float? || obj is double? || obj is bool?)
|
||||
{
|
||||
return "{0}".InvariantFormat(obj);
|
||||
}
|
||||
@@ -435,6 +568,5 @@ namespace Umbraco.Core
|
||||
return "[GetPropertyValueException]";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
@@ -82,8 +84,8 @@ namespace Umbraco.Tests
|
||||
{
|
||||
var result = testCase.Key.TryConvertTo<bool>();
|
||||
|
||||
Assert.IsTrue(result.Success);
|
||||
Assert.AreEqual(testCase.Value, result.Result);
|
||||
Assert.IsTrue(result.Success, testCase.Key);
|
||||
Assert.AreEqual(testCase.Value, result.Result, testCase.Key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,34 +97,41 @@ namespace Umbraco.Tests
|
||||
{
|
||||
{"2012-11-10", true},
|
||||
{"2012/11/10", true},
|
||||
{"10/11/2012", true},
|
||||
{"11/10/2012", false},
|
||||
{"10/11/2012", true}, // assuming your culture uses DD/MM/YYYY
|
||||
{"11/10/2012", false}, // assuming your culture uses DD/MM/YYYY
|
||||
{"Sat 10, Nov 2012", true},
|
||||
{"Saturday 10, Nov 2012", true},
|
||||
{"Sat 10, November 2012", true},
|
||||
{"Saturday 10, November 2012", true},
|
||||
{"2012-11-10 13:14:15", true},
|
||||
{"", false}
|
||||
{"2012-11-10 13:14:15", true}
|
||||
};
|
||||
|
||||
foreach (var testCase in testCases)
|
||||
{
|
||||
var result = testCase.Key.TryConvertTo<DateTime>();
|
||||
|
||||
Assert.IsTrue(result.Success);
|
||||
Assert.AreEqual(DateTime.Equals(dateTime.Date, result.Result.Date), testCase.Value);
|
||||
Assert.IsTrue(result.Success, testCase.Key);
|
||||
Assert.AreEqual(DateTime.Equals(dateTime.Date, result.Result.Date), testCase.Value, testCase.Key);
|
||||
}
|
||||
}
|
||||
[Test]
|
||||
public virtual void CanConvertObjectToString_Using_ToString_Overload()
|
||||
{
|
||||
var result = new MyTestObject().TryConvertTo<string>();
|
||||
[Test]
|
||||
public virtual void CanConvertBlankStringToDateTime()
|
||||
{
|
||||
var result = "".TryConvertTo<DateTime>();
|
||||
Assert.IsTrue(result.Success);
|
||||
Assert.AreEqual(DateTime.MinValue, result.Result);
|
||||
}
|
||||
|
||||
Assert.IsTrue(result.Success);
|
||||
Assert.AreEqual("Hello world", result.Result);
|
||||
}
|
||||
[Test]
|
||||
public virtual void CanConvertObjectToString_Using_ToString_Overload()
|
||||
{
|
||||
var result = new MyTestObject().TryConvertTo<string>();
|
||||
|
||||
[Test]
|
||||
Assert.IsTrue(result.Success);
|
||||
Assert.AreEqual("Hello world", result.Result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public virtual void CanConvertObjectToSameObject()
|
||||
{
|
||||
var obj = new MyTestObject();
|
||||
@@ -130,7 +139,27 @@ namespace Umbraco.Tests
|
||||
|
||||
Assert.AreEqual(obj, result);
|
||||
}
|
||||
|
||||
private CultureInfo savedCulture;
|
||||
|
||||
/// <summary>
|
||||
/// Run once before each test in derived test fixtures.
|
||||
/// </summary>
|
||||
public override void TestSetup()
|
||||
{
|
||||
savedCulture = Thread.CurrentThread.CurrentCulture;
|
||||
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB"); // make sure the dates parse correctly
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run once after each test in derived test fixtures.
|
||||
/// </summary>
|
||||
public override void TestTearDown()
|
||||
{
|
||||
Thread.CurrentThread.CurrentCulture = savedCulture;
|
||||
return;
|
||||
}
|
||||
|
||||
private class MyTestObject
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Data.SqlClient;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Cache;
|
||||
using UmbracoExamine;
|
||||
using UmbracoExamine.DataServices;
|
||||
using umbraco;
|
||||
@@ -67,7 +68,7 @@ namespace Umbraco.Tests
|
||||
|
||||
var t6 = TypeHelper.GetLowestBaseType(typeof (IApplicationEventHandler),
|
||||
typeof (LegacyScheduledTasks),
|
||||
typeof(CacheHelperExtensions.CacheHelperApplicationEventListener));
|
||||
typeof(CacheRefresherEventHandler));
|
||||
Assert.IsTrue(t6.Success);
|
||||
Assert.AreEqual(typeof(IApplicationEventHandler), t6.Result);
|
||||
|
||||
|
||||
@@ -111,6 +111,8 @@ namespace Umbraco.Web.Cache
|
||||
{
|
||||
if (payloads == null) return;
|
||||
|
||||
ApplicationContext.Current.ApplicationCache.ClearPartialViewCache();
|
||||
|
||||
payloads.ForEach(payload =>
|
||||
{
|
||||
foreach (var idPart in payload.Path.Split(','))
|
||||
|
||||
@@ -44,6 +44,8 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
private void ClearCache(int id)
|
||||
{
|
||||
ApplicationContext.Current.ApplicationCache.ClearPartialViewCache();
|
||||
|
||||
ApplicationContext.Current.ApplicationCache.
|
||||
ClearCacheByKeySearch(string.Format("{0}_{1}", CacheKeys.MemberLibraryCacheKey, id));
|
||||
ApplicationContext.Current.ApplicationCache.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Sync;
|
||||
@@ -58,6 +59,7 @@ namespace Umbraco.Web.Cache
|
||||
/// <param name="id">The id.</param>
|
||||
public override void Refresh(int id)
|
||||
{
|
||||
ApplicationContext.Current.ApplicationCache.ClearPartialViewCache();
|
||||
content.Instance.UpdateDocumentCache(id);
|
||||
DistributedCache.Instance.ClearAllMacroCacheOnCurrentServer();
|
||||
DistributedCache.Instance.ClearXsltCacheOnCurrentServer();
|
||||
@@ -70,6 +72,7 @@ namespace Umbraco.Web.Cache
|
||||
/// <param name="id">The id.</param>
|
||||
public override void Remove(int id)
|
||||
{
|
||||
ApplicationContext.Current.ApplicationCache.ClearPartialViewCache();
|
||||
content.Instance.ClearDocumentCache(id);
|
||||
DistributedCache.Instance.ClearAllMacroCacheOnCurrentServer();
|
||||
DistributedCache.Instance.ClearXsltCacheOnCurrentServer();
|
||||
@@ -78,6 +81,7 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
public override void Refresh(IContent instance)
|
||||
{
|
||||
ApplicationContext.Current.ApplicationCache.ClearPartialViewCache();
|
||||
content.Instance.UpdateDocumentCache(new Document(instance));
|
||||
DistributedCache.Instance.ClearAllMacroCacheOnCurrentServer();
|
||||
DistributedCache.Instance.ClearXsltCacheOnCurrentServer();
|
||||
@@ -86,6 +90,7 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
public override void Remove(IContent instance)
|
||||
{
|
||||
ApplicationContext.Current.ApplicationCache.ClearPartialViewCache();
|
||||
content.Instance.ClearDocumentCache(new Document(instance));
|
||||
DistributedCache.Instance.ClearAllMacroCacheOnCurrentServer();
|
||||
DistributedCache.Instance.ClearXsltCacheOnCurrentServer();
|
||||
|
||||
@@ -14,32 +14,6 @@ namespace Umbraco.Web
|
||||
/// </summary>
|
||||
internal static class CacheHelperExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Application event handler to bind to events to clear the cache for the cache helper extensions
|
||||
/// </summary>
|
||||
internal sealed class CacheHelperApplicationEventListener : ApplicationEventHandler
|
||||
{
|
||||
protected override void ApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
if (applicationContext != null)
|
||||
{
|
||||
//bind to events to clear the cache, after publish, after media save and after member save
|
||||
|
||||
Document.AfterPublish
|
||||
+= (sender, args) =>
|
||||
applicationContext.ApplicationCache.ClearPartialViewCache();
|
||||
|
||||
global::umbraco.cms.businesslogic.media.Media.AfterSave
|
||||
+= (sender, args) =>
|
||||
applicationContext.ApplicationCache.ClearPartialViewCache();
|
||||
|
||||
global::umbraco.cms.businesslogic.member.Member.AfterSave
|
||||
+= (sender, args) =>
|
||||
applicationContext.ApplicationCache.ClearPartialViewCache();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public const string PartialViewCacheKey = "Umbraco.Web.PartialViewCacheKey";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user