Merge dev-v7.6 into temp-u4-9462

This commit is contained in:
Stephan
2017-03-09 15:29:26 +01:00
250 changed files with 4740 additions and 1620 deletions
+3 -3
View File
@@ -24,7 +24,7 @@
<dependency id="Microsoft.Owin.Security.OAuth" version="[3.0.1, 4.0.0)" />
<dependency id="Microsoft.Owin.Host.SystemWeb" version="[3.0.1, 4.0.0)" />
<dependency id="MiniProfiler" version="[2.1.0, 3.0.0)" />
<dependency id="HtmlAgilityPack" version="[1.4.9, 2.0.0)" />
<dependency id="HtmlAgilityPack" version="[1.4.9.5, 2.0.0)" />
<dependency id="Lucene.Net" version="[2.9.4.1, 3.0.0.0)" />
<dependency id="SharpZipLib" version="[0.86.0, 1.0.0)" />
<dependency id="MySql.Data" version="[6.9.8, 7.0.0)" />
@@ -37,9 +37,9 @@
<dependency id="ImageProcessor" version="[2.5.2, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[4.8.2, 5.0.0)" />
<dependency id="semver" version="[2.0.4, 3.0.0)" />
<dependency id="UrlRewritingNet" version="[2.0.7, 3.0.0)" />
<dependency id="UrlRewritingNet" version="[2.0.7, 3.0.0)" />
<!-- Markdown can not be updated due to: https://github.com/hey-red/markdownsharp/issues/71#issuecomment-233585487 -->
<dependency id="Markdown" version="[1.14.7, 2.0.0)" />
<dependency id="Markdown" version="[1.14.7, 2.0.0)" />
<dependency id="System.Threading.Tasks.Dataflow" version="[4.6.0, 5.0.0)" />
</dependencies>
</metadata>
+1 -1
View File
@@ -1,3 +1,3 @@
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
7.6.0
alpha065
alpha074
+3 -1
View File
@@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SQLCE4Umbraco</RootNamespace>
<AssemblyName>SQLCE4Umbraco</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SccProjectName>
</SccProjectName>
@@ -49,9 +49,11 @@
<Reference Include="System.Core" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
+1 -1
View File
@@ -32,4 +32,4 @@
</dependentAssembly>
</assemblyBinding>
</runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" /></startup></configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /></startup></configuration>
+1 -1
View File
@@ -12,4 +12,4 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.6.0")]
[assembly: AssemblyInformationalVersion("7.6.0-alpha065")]
[assembly: AssemblyInformationalVersion("7.6.0-alpha074")]
@@ -0,0 +1,27 @@
using System;
namespace Umbraco.Core.Configuration
{
internal static class CoreDebugExtensions
{
private static CoreDebug _coreDebug;
public static CoreDebug CoreDebug(this UmbracoConfig config)
{
return _coreDebug ?? (_coreDebug = new CoreDebug());
}
}
internal class CoreDebug
{
public CoreDebug()
{
var appSettings = System.Configuration.ConfigurationManager.AppSettings;
LogUncompletedScopes = string.Equals("true", appSettings["Umbraco.CoreDebug.LogUncompletedScopes"], StringComparison.OrdinalIgnoreCase);
}
// when true, Scope logs the stack trace for any scope that gets disposed without being completed.
// this helps troubleshooting rogue scopes that we forget to complete
public bool LogUncompletedScopes { get; private set; }
}
}
@@ -177,6 +177,12 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
get { return GetOptionalTextElement("EnableInheritedMediaTypes", true); }
}
[ConfigurationProperty("EnablePropertyValueConverters")]
internal InnerTextConfigurationElement<bool> EnablePropertyValueConverters
{
get { return GetOptionalTextElement("EnablePropertyValueConverters", false); }
}
string IContentSection.NotificationEmailAddress
{
get { return Notifications.NotificationEmailAddress; }
@@ -326,5 +332,9 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
{
get { return EnableInheritedMediaTypes; }
}
bool IContentSection.EnablePropertyValueConverters
{
get { return EnablePropertyValueConverters; }
}
}
}
@@ -69,5 +69,8 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
bool EnableInheritedDocumentTypes { get; }
bool EnableInheritedMediaTypes { get; }
bool EnablePropertyValueConverters { get; }
}
}
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Configuration
/// Gets the version comment (like beta or RC).
/// </summary>
/// <value>The version comment.</value>
public static string CurrentComment { get { return "alpha065"; } }
public static string CurrentComment { get { return "alpha074"; } }
// Get the version of the umbraco.dll by looking at a class in that dll
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
+4 -4
View File
@@ -70,16 +70,16 @@ namespace Umbraco.Core.Deploy
/// Gets files and store them using a file store.
/// </summary>
/// <param name="udis">The udis of the files to get.</param>
/// <param name="fileStore">A file store which can store the files.</param>
void GetFiles(IEnumerable<StringUdi> udis, IFileStore fileStore);
/// <param name="fileTypes">A collection of file types which can store the files.</param>
void GetFiles(IEnumerable<StringUdi> udis, IFileTypeCollection fileTypes);
/// <summary>
/// Gets files and store them using a file store.
/// </summary>
/// <param name="udis">The udis of the files to get.</param>
/// <param name="fileStore">A file store which can store the files.</param>
/// <param name="fileTypes">A collection of file types which can store the files.</param>
/// <param name="token">A cancellation token.</param>
Task GetFilesAsync(IEnumerable<StringUdi> udis, IFileStore fileStore, CancellationToken token);
Task GetFilesAsync(IEnumerable<StringUdi> udis, IFileTypeCollection fileTypes, CancellationToken token);
///// <summary>
///// Gets the content of a file as a bytes array.
-9
View File
@@ -1,9 +0,0 @@
using System.IO;
namespace Umbraco.Core.Deploy
{
public interface IFileStore
{
void SaveStream(StringUdi udi, Stream stream);
}
}
+32
View File
@@ -0,0 +1,32 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace Umbraco.Core.Deploy
{
public interface IFileType
{
Stream GetStream(StringUdi udi);
Task<Stream> GetStreamAsync(StringUdi udi, CancellationToken token);
Stream GetChecksumStream(StringUdi udi);
long GetLength(StringUdi udi);
void SetStream(StringUdi udi, Stream stream);
Task SetStreamAsync(StringUdi udi, Stream stream, CancellationToken token);
bool CanSetPhysical { get; }
void Set(StringUdi udi, string physicalPath, bool copy = false);
// this is not pretty as *everywhere* in Deploy we take care of ignoring
// the physical path and always rely on Core's virtual IFileSystem but
// Cloud wants to add some of these files to Git and needs the path...
string GetPhysicalPath(StringUdi udi);
string GetVirtualPath(StringUdi udi);
}
}
@@ -0,0 +1,9 @@
namespace Umbraco.Core.Deploy
{
public interface IFileTypeCollection
{
IFileType this[string entityType] { get; }
bool Contains(string entityType);
}
}
+16
View File
@@ -296,5 +296,21 @@ namespace Umbraco.Core
&& list1Groups.All(g => g.Count() == list2Groups[g.Key].Count());
}
///<summary>
/// Returns the items of the given enumerable as a pure enumerable.
/// <remarks>
/// When quering lists using methods such as <see cref="M:List.Where"/>, the result, despite appearing to look like and quack like an
/// <see cref="T:Enumerable{T}"/> the type is actually an instance of <see cref="T:System.Linq.Enumerable.WhereEnumerableIterator"/>
/// </remarks>
/// </summary>
///<param name="source">The item to find.</param>
///<returns>The index of the first matching item, or -1 if the item was not found.</returns>
internal static IEnumerable<T> Yield<T>(this IEnumerable<T> source)
{
foreach (var element in source)
{
yield return element;
}
}
}
}
+168 -120
View File
@@ -12,25 +12,18 @@ namespace Umbraco.Core.IO
public class FileSystemProviderManager
{
private readonly FileSystemProvidersSection _config;
private readonly WeakSet<ShadowWrapper> _wrappers = new WeakSet<ShadowWrapper>();
private readonly ConcurrentSet<ShadowWrapper> _wrappers = new ConcurrentSet<ShadowWrapper>();
// actual well-known filesystems returned by properties
private readonly IFileSystem2 _macroPartialFileSystem;
private readonly IFileSystem2 _partialViewsFileSystem;
private readonly IFileSystem2 _stylesheetsFileSystem;
private readonly IFileSystem2 _scriptsFileSystem;
private readonly IFileSystem2 _xsltFileSystem;
private readonly IFileSystem2 _masterPagesFileSystem;
private readonly IFileSystem2 _mvcViewsFileSystem;
private readonly ConcurrentDictionary<string, ProviderConstructionInfo> _providerLookup = new ConcurrentDictionary<string, ProviderConstructionInfo>();
private readonly ConcurrentDictionary<string, IFileSystem2> _filesystems = new ConcurrentDictionary<string, IFileSystem2>();
// when shadowing is enabled, above filesystems, as wrappers
private readonly ShadowWrapper _macroPartialFileSystemWrapper;
private readonly ShadowWrapper _partialViewsFileSystemWrapper;
private readonly ShadowWrapper _stylesheetsFileSystemWrapper;
private readonly ShadowWrapper _scriptsFileSystemWrapper;
private readonly ShadowWrapper _xsltFileSystemWrapper;
private readonly ShadowWrapper _masterPagesFileSystemWrapper;
private readonly ShadowWrapper _mvcViewsFileSystemWrapper;
private ShadowWrapper _macroPartialFileSystem;
private ShadowWrapper _partialViewsFileSystem;
private ShadowWrapper _stylesheetsFileSystem;
private ShadowWrapper _scriptsFileSystem;
private ShadowWrapper _xsltFileSystem;
private ShadowWrapper _masterPagesFileSystem;
private ShadowWrapper _mvcViewsFileSystem;
#region Singleton & Constructor
@@ -41,32 +34,46 @@ namespace Umbraco.Core.IO
get { return Instance; }
}
// for tests only, totally unsafe
internal void Reset()
{
_wrappers.Clear();
_providerLookup.Clear();
_filesystems.Clear();
CreateWellKnownFileSystems();
}
private IScopeProviderInternal ScopeProvider
{
// this is bad, but enough for now, and we'll refactor
// in v8 when we'll get rid of this class' singleton
// beware: means that we capture the "current" scope provider - take care in tests!
get { return ApplicationContext.Current == null ? null : ApplicationContext.Current.ScopeProvider as IScopeProviderInternal; }
}
internal FileSystemProviderManager()
{
_config = (FileSystemProvidersSection) ConfigurationManager.GetSection("umbracoConfiguration/FileSystemProviders");
CreateWellKnownFileSystems();
}
_macroPartialFileSystem = new PhysicalFileSystem(SystemDirectories.MacroPartials);
_partialViewsFileSystem = new PhysicalFileSystem(SystemDirectories.PartialViews);
_stylesheetsFileSystem = new PhysicalFileSystem(SystemDirectories.Css);
_scriptsFileSystem = new PhysicalFileSystem(SystemDirectories.Scripts);
_xsltFileSystem = new PhysicalFileSystem(SystemDirectories.Xslt);
_masterPagesFileSystem = new PhysicalFileSystem(SystemDirectories.Masterpages);
_mvcViewsFileSystem = new PhysicalFileSystem(SystemDirectories.MvcViews);
private void CreateWellKnownFileSystems()
{
var macroPartialFileSystem = new PhysicalFileSystem(SystemDirectories.MacroPartials);
var partialViewsFileSystem = new PhysicalFileSystem(SystemDirectories.PartialViews);
var stylesheetsFileSystem = new PhysicalFileSystem(SystemDirectories.Css);
var scriptsFileSystem = new PhysicalFileSystem(SystemDirectories.Scripts);
var xsltFileSystem = new PhysicalFileSystem(SystemDirectories.Xslt);
var masterPagesFileSystem = new PhysicalFileSystem(SystemDirectories.Masterpages);
var mvcViewsFileSystem = new PhysicalFileSystem(SystemDirectories.MvcViews);
_macroPartialFileSystem = _macroPartialFileSystemWrapper = new ShadowWrapper(_macroPartialFileSystem, "Views/MacroPartials", ScopeProvider);
_partialViewsFileSystem = _partialViewsFileSystemWrapper = new ShadowWrapper(_partialViewsFileSystem, "Views/Partials", ScopeProvider);
_stylesheetsFileSystem = _stylesheetsFileSystemWrapper = new ShadowWrapper(_stylesheetsFileSystem, "css", ScopeProvider);
_scriptsFileSystem = _scriptsFileSystemWrapper = new ShadowWrapper(_scriptsFileSystem, "scripts", ScopeProvider);
_xsltFileSystem = _xsltFileSystemWrapper = new ShadowWrapper(_xsltFileSystem, "xslt", ScopeProvider);
_masterPagesFileSystem = _masterPagesFileSystemWrapper = new ShadowWrapper(_masterPagesFileSystem, "masterpages", ScopeProvider);
_mvcViewsFileSystem = _mvcViewsFileSystemWrapper = new ShadowWrapper(_mvcViewsFileSystem, "Views", ScopeProvider);
_macroPartialFileSystem = new ShadowWrapper(macroPartialFileSystem, "Views/MacroPartials", ScopeProvider);
_partialViewsFileSystem = new ShadowWrapper(partialViewsFileSystem, "Views/Partials", ScopeProvider);
_stylesheetsFileSystem = new ShadowWrapper(stylesheetsFileSystem, "css", ScopeProvider);
_scriptsFileSystem = new ShadowWrapper(scriptsFileSystem, "scripts", ScopeProvider);
_xsltFileSystem = new ShadowWrapper(xsltFileSystem, "xslt", ScopeProvider);
_masterPagesFileSystem = new ShadowWrapper(masterPagesFileSystem, "masterpages", ScopeProvider);
_mvcViewsFileSystem = new ShadowWrapper(mvcViewsFileSystem, "Views", ScopeProvider);
// filesystems obtained from GetFileSystemProvider are already wrapped and do not need to be wrapped again
MediaFileSystem = GetFileSystemProvider<MediaFileSystem>();
@@ -81,7 +88,7 @@ namespace Umbraco.Core.IO
public IFileSystem2 StylesheetsFileSystem { get { return _stylesheetsFileSystem; } }
public IFileSystem2 ScriptsFileSystem { get { return _scriptsFileSystem; } }
public IFileSystem2 XsltFileSystem { get { return _xsltFileSystem; } }
public IFileSystem2 MasterPagesFileSystem { get { return _masterPagesFileSystem; } }
public IFileSystem2 MasterPagesFileSystem { get { return _mvcViewsFileSystem; } }
public IFileSystem2 MvcViewsFileSystem { get { return _mvcViewsFileSystem; } }
public MediaFileSystem MediaFileSystem { get; private set; }
@@ -99,56 +106,74 @@ namespace Umbraco.Core.IO
//public string ProviderAlias { get; set; }
}
private readonly ConcurrentDictionary<string, ProviderConstructionInfo> _providerLookup = new ConcurrentDictionary<string, ProviderConstructionInfo>();
private readonly ConcurrentDictionary<Type, string> _aliases = new ConcurrentDictionary<Type, string>();
/// <summary>
/// Gets an underlying (non-typed) filesystem supporting a strongly-typed filesystem.
/// </summary>
/// <param name="alias">The alias of the strongly-typed filesystem.</param>
/// <returns>The non-typed filesystem supporting the strongly-typed filesystem with the specified alias.</returns>
/// <remarks>This method should not be used directly, used <see cref="GetFileSystemProvider{TFileSystem}"/> instead.</remarks>
/// <remarks>This method should not be used directly, used <see cref="GetFileSystemProvider{TFileSystem}()"/> instead.</remarks>
public IFileSystem GetUnderlyingFileSystemProvider(string alias)
{
return GetUnderlyingFileSystemProvider(alias, null);
}
/// <summary>
/// Gets an underlying (non-typed) filesystem supporting a strongly-typed filesystem.
/// </summary>
/// <param name="alias">The alias of the strongly-typed filesystem.</param>
/// /// <param name="fallback">A fallback creator for the filesystem.</param>
/// <returns>The non-typed filesystem supporting the strongly-typed filesystem with the specified alias.</returns>
/// <remarks>This method should not be used directly, used <see cref="GetFileSystemProvider{TFileSystem}()"/> instead.</remarks>
private IFileSystem GetUnderlyingFileSystemProvider(string alias, Func<IFileSystem> fallback)
{
// either get the constructor info from cache or create it and add to cache
var ctorInfo = _providerLookup.GetOrAdd(alias, s =>
{
// get config
var providerConfig = _config.Providers[s];
if (providerConfig == null)
throw new ArgumentException(string.Format("No provider found with alias {0}.", s));
var ctorInfo = _providerLookup.GetOrAdd(alias, _ => GetUnderlyingFileSystemCtor(alias, fallback));
return ctorInfo == null ? fallback() : (IFileSystem) ctorInfo.Constructor.Invoke(ctorInfo.Parameters);
}
// get the filesystem type
var providerType = Type.GetType(providerConfig.Type);
if (providerType == null)
throw new InvalidOperationException(string.Format("Could not find type {0}.", providerConfig.Type));
private IFileSystem GetUnderlyingFileSystemNoCache(string alias, Func<IFileSystem> fallback)
{
var ctorInfo = GetUnderlyingFileSystemCtor(alias, fallback);
return ctorInfo == null ? fallback() : (IFileSystem) ctorInfo.Constructor.Invoke(ctorInfo.Parameters);
}
// ensure it implements IFileSystem
if (providerType.IsAssignableFrom(typeof (IFileSystem)))
throw new InvalidOperationException(string.Format("Type {0} does not implement IFileSystem.", providerType.FullName));
private ProviderConstructionInfo GetUnderlyingFileSystemCtor(string alias, Func<IFileSystem> fallback)
{
// get config
var providerConfig = _config.Providers[alias];
if (providerConfig == null)
{
if (fallback != null) return null;
throw new ArgumentException(string.Format("No provider found with alias {0}.", alias));
}
// find a ctor matching the config parameters
var paramCount = providerConfig.Parameters != null ? providerConfig.Parameters.Count : 0;
var constructor = providerType.GetConstructors().SingleOrDefault(x
=> x.GetParameters().Length == paramCount && x.GetParameters().All(y => providerConfig.Parameters.AllKeys.Contains(y.Name)));
if (constructor == null)
throw new InvalidOperationException(string.Format("Type {0} has no ctor matching the {1} configuration parameter(s).", providerType.FullName, paramCount));
// get the filesystem type
var providerType = Type.GetType(providerConfig.Type);
if (providerType == null)
throw new InvalidOperationException(string.Format("Could not find type {0}.", providerConfig.Type));
var parameters = new object[paramCount];
if (providerConfig.Parameters != null) // keeps ReSharper happy
for (var i = 0; i < paramCount; i++)
parameters[i] = providerConfig.Parameters[providerConfig.Parameters.AllKeys[i]].Value;
// ensure it implements IFileSystem
if (providerType.IsAssignableFrom(typeof(IFileSystem)))
throw new InvalidOperationException(string.Format("Type {0} does not implement IFileSystem.", providerType.FullName));
return new ProviderConstructionInfo
{
Constructor = constructor,
Parameters = parameters,
//ProviderAlias = s
};
});
// find a ctor matching the config parameters
var paramCount = providerConfig.Parameters != null ? providerConfig.Parameters.Count : 0;
var constructor = providerType.GetConstructors().SingleOrDefault(x
=> x.GetParameters().Length == paramCount && x.GetParameters().All(y => providerConfig.Parameters.AllKeys.Contains(y.Name)));
if (constructor == null)
throw new InvalidOperationException(string.Format("Type {0} has no ctor matching the {1} configuration parameter(s).", providerType.FullName, paramCount));
// create the fs and return
return (IFileSystem) ctorInfo.Constructor.Invoke(ctorInfo.Parameters);
var parameters = new object[paramCount];
if (providerConfig.Parameters != null) // keeps ReSharper happy
for (var i = 0; i < paramCount; i++)
parameters[i] = providerConfig.Parameters[providerConfig.Parameters.AllKeys[i]].Value;
return new ProviderConstructionInfo
{
Constructor = constructor,
Parameters = parameters,
//ProviderAlias = s
};
}
/// <summary>
@@ -156,38 +181,68 @@ namespace Umbraco.Core.IO
/// </summary>
/// <typeparam name="TFileSystem">The type of the filesystem.</typeparam>
/// <returns>A strongly-typed filesystem of the specified type.</returns>
/// <remarks>
/// <para>Ideally, this should cache the instances, but that would break backward compatibility, so we
/// only do it for our own MediaFileSystem - for everything else, it's the responsibility of the caller
/// to ensure that they maintain singletons. This is important for singletons, as each filesystem maintains
/// its own shadow and having multiple instances would lead to inconsistencies.</para>
/// <para>Note that any filesystem created by this method *after* shadowing begins, will *not* be
/// shadowing (and an exception will be thrown by the ShadowWrapper).</para>
/// </remarks>
public TFileSystem GetFileSystemProvider<TFileSystem>()
where TFileSystem : FileSystemWrapper
where TFileSystem : FileSystemWrapper
{
// deal with known types - avoid infinite loops!
if (typeof(TFileSystem) == typeof(MediaFileSystem) && MediaFileSystem != null)
return MediaFileSystem as TFileSystem; // else create and return
return GetFileSystemProvider<TFileSystem>(null);
}
// get/cache the alias for the filesystem type
var alias = _aliases.GetOrAdd(typeof (TFileSystem), fsType =>
{
// validate the ctor
var constructor = fsType.GetConstructors().SingleOrDefault(x
=> x.GetParameters().Length == 1 && TypeHelper.IsTypeAssignableFrom<IFileSystem>(x.GetParameters().Single().ParameterType));
if (constructor == null)
throw new InvalidOperationException("Type " + fsType.FullName + " must inherit from FileSystemWrapper and have a constructor that accepts one parameter of type " + typeof(IFileSystem).FullName + ".");
/// <summary>
/// Gets a strongly-typed filesystem.
/// </summary>
/// <typeparam name="TFileSystem">The type of the filesystem.</typeparam>
/// <param name="fallback">A fallback creator for the inner filesystem.</param>
/// <returns>A strongly-typed filesystem of the specified type.</returns>
/// <remarks>
/// <para>The fallback creator is used only if nothing is configured.</para>
/// <para>Ideally, this should cache the instances, but that would break backward compatibility, so we
/// only do it for our own MediaFileSystem - for everything else, it's the responsibility of the caller
/// to ensure that they maintain singletons. This is important for singletons, as each filesystem maintains
/// its own shadow and having multiple instances would lead to inconsistencies.</para>
/// <para>Note that any filesystem created by this method *after* shadowing begins, will *not* be
/// shadowing (and an exception will be thrown by the ShadowWrapper).</para>
/// </remarks>
public TFileSystem GetFileSystemProvider<TFileSystem>(Func<IFileSystem> fallback)
where TFileSystem : FileSystemWrapper
{
var alias = GetFileSystemAlias<TFileSystem>();
return (TFileSystem) _filesystems.GetOrAdd(alias, _ =>
{
// gets the inner fs, create the strongly-typed fs wrapping the inner fs, register & return
// so we are double-wrapping here
// could be optimized by having FileSystemWrapper inherit from ShadowWrapper, maybe
var innerFs = GetUnderlyingFileSystemNoCache(alias, fallback);
var shadowWrapper = new ShadowWrapper(innerFs, "typed/" + alias, ScopeProvider);
var fs = (IFileSystem2) Activator.CreateInstance(typeof (TFileSystem), shadowWrapper);
_wrappers.Add(shadowWrapper); // keeping a reference to the wrapper
return fs;
});
}
// find the attribute and get the alias
var attr = (FileSystemProviderAttribute) fsType.GetCustomAttributes(typeof(FileSystemProviderAttribute), false).SingleOrDefault();
if (attr == null)
throw new InvalidOperationException("Type " + fsType.FullName + "is missing the required FileSystemProviderAttribute.");
private string GetFileSystemAlias<TFileSystem>()
{
var fsType = typeof(TFileSystem);
return attr.Alias;
});
// validate the ctor
var constructor = fsType.GetConstructors().SingleOrDefault(x
=> x.GetParameters().Length == 1 && TypeHelper.IsTypeAssignableFrom<IFileSystem>(x.GetParameters().Single().ParameterType));
if (constructor == null)
throw new InvalidOperationException("Type " + fsType.FullName + " must inherit from FileSystemWrapper and have a constructor that accepts one parameter of type " + typeof(IFileSystem).FullName + ".");
// gets the inner fs, create the strongly-typed fs wrapping the inner fs, register & return
// so we are double-wrapping here
// could be optimized by having FileSystemWrapper inherit from ShadowWrapper, maybe
var innerFs = GetUnderlyingFileSystemProvider(alias);
var shadowWrapper = new ShadowWrapper(innerFs, "typed/" + alias, ScopeProvider);
var fs = (TFileSystem) Activator.CreateInstance(typeof (TFileSystem), shadowWrapper);
_wrappers.Add(shadowWrapper); // keeping a weak reference to the wrapper
return fs;
// find the attribute and get the alias
var attr = (FileSystemProviderAttribute)fsType.GetCustomAttributes(typeof(FileSystemProviderAttribute), false).SingleOrDefault();
if (attr == null)
throw new InvalidOperationException("Type " + fsType.FullName + "is missing the required FileSystemProviderAttribute.");
return attr.Alias;
}
#endregion
@@ -200,30 +255,37 @@ namespace Umbraco.Core.IO
var wrappers = new ShadowWrapper[typed.Length + 7];
var i = 0;
while (i < typed.Length) wrappers[i] = typed[i++];
wrappers[i++] = _macroPartialFileSystemWrapper;
wrappers[i++] = _partialViewsFileSystemWrapper;
wrappers[i++] = _stylesheetsFileSystemWrapper;
wrappers[i++] = _scriptsFileSystemWrapper;
wrappers[i++] = _xsltFileSystemWrapper;
wrappers[i++] = _masterPagesFileSystemWrapper;
wrappers[i] = _mvcViewsFileSystemWrapper;
wrappers[i++] = _macroPartialFileSystem;
wrappers[i++] = _partialViewsFileSystem;
wrappers[i++] = _stylesheetsFileSystem;
wrappers[i++] = _scriptsFileSystem;
wrappers[i++] = _xsltFileSystem;
wrappers[i++] = _masterPagesFileSystem;
wrappers[i] = _mvcViewsFileSystem;
return new ShadowFileSystems(id, wrappers);
}
#endregion
private class WeakSet<T>
private class ConcurrentSet<T>
where T : class
{
private readonly HashSet<WeakReference<T>> _set = new HashSet<WeakReference<T>>();
private readonly HashSet<T> _set = new HashSet<T>();
public void Add(T item)
{
lock (_set)
{
_set.Add(new WeakReference<T>(item));
CollectLocked();
_set.Add(item);
}
}
public void Clear()
{
lock (_set)
{
_set.Clear();
}
}
@@ -231,23 +293,9 @@ namespace Umbraco.Core.IO
{
lock (_set)
{
CollectLocked();
return _set.Select(x =>
{
T target;
return x.TryGetTarget(out target) ? target : null;
}).WhereNotNull().ToArray();
return _set.ToArray();
}
}
private void CollectLocked()
{
_set.RemoveWhere(x =>
{
T target;
return x.TryGetTarget(out target) == false;
});
}
}
}
}
+6 -1
View File
@@ -27,7 +27,7 @@ namespace Umbraco.Core.IO
// on ShadowFileSystemsScope.None - and if None is false then we should be running
// in a single thread anyways
var virt = "~/App_Data/Shadow/" + id + "/" + _shadowPath;
var virt = "~/App_Data/TEMP/ShadowFs/" + id + "/" + _shadowPath;
_shadowDir = IOHelper.MapPath(virt);
Directory.CreateDirectory(_shadowDir);
var tempfs = new PhysicalFileSystem(virt);
@@ -69,6 +69,11 @@ namespace Umbraco.Core.IO
{
var isScoped = _scopeProvider != null && _scopeProvider.AmbientScope != null && _scopeProvider.AmbientScope.ScopedFileSystems;
// if the filesystem is created *after* shadowing starts, it won't be shadowing
// better not ignore that situation and raised a meaningful (?) exception
if (isScoped && _shadowFileSystem == null)
throw new Exception("The filesystems are shadowing, but this filesystem is not.");
return isScoped
? _shadowFileSystem
: _innerFileSystem;
@@ -0,0 +1,63 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// The published content enumerable, this model is to allow ToString to be overriden for value converters to support legacy requests for string values
/// </summary>
public class PublishedContentEnumerable : IEnumerable<IPublishedContent>
{
/// <summary>
/// The items in the collection
/// </summary>
private readonly IEnumerable<IPublishedContent> _items;
/// <summary>
/// Initializes a new instance of the <see cref="PublishedContentEnumerable"/> class.
/// </summary>
/// <param name="publishedContent">
/// The published content items
/// </param>
public PublishedContentEnumerable(IEnumerable<IPublishedContent> publishedContent)
{
if (publishedContent == null) throw new ArgumentNullException("publishedContent");
_items = publishedContent;
}
/// <summary>
/// The ToString method to convert the objects back to CSV
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// </returns>
public override string ToString()
{
return string.Join(",", _items.Select(x => x.Id));
}
/// <summary>
/// The get enumerator.
/// </summary>
/// <returns>
/// The <see cref="IEnumerator"/>.
/// </returns>
public IEnumerator<IPublishedContent> GetEnumerator()
{
return _items.GetEnumerator();
}
/// <summary>
/// The get enumerator.
/// </summary>
/// <returns>
/// The <see cref="IEnumerator"/>.
/// </returns>
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
@@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
namespace Umbraco.Core.Models.PublishedContent
{
[TypeConverter(typeof(PublishedContentTypeConverter))]
public class PublishedContentExtended : PublishedContentWrapped, IPublishedContentExtended
{
#region Constructor
@@ -186,6 +187,11 @@ namespace Umbraco.Core.Models.PublishedContent
}
#endregion
public override string ToString()
{
return Id.ToString();
}
}
}
@@ -0,0 +1,39 @@
using System;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
namespace Umbraco.Core.Models.PublishedContent
{
internal class PublishedContentTypeConverter : TypeConverter
{
private static readonly Type[] ConvertableTypes = new[]
{
typeof(int)
};
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return ConvertableTypes.Any(x => TypeHelper.IsTypeAssignableFrom(x, destinationType))
|| base.CanConvertFrom(context, destinationType);
}
public override object ConvertTo(
ITypeDescriptorContext context,
CultureInfo culture,
object value,
Type destinationType)
{
var publishedContent = value as IPublishedContent;
if (publishedContent == null)
return null;
if (TypeHelper.IsTypeAssignableFrom<int>(destinationType))
{
return publishedContent.Id;
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
}
+52
View File
@@ -0,0 +1,52 @@
using System;
namespace Umbraco.Core.Models
{
// <summary>The Range class. Adapted from http://stackoverflow.com/questions/5343006/is-there-a-c-sharp-type-for-representing-an-integer-range</summary>
/// <typeparam name="T">Generic parameter.</typeparam>
public class Range<T> where T : IComparable<T>
{
/// <summary>Minimum value of the range.</summary>
public T Minimum { get; set; }
/// <summary>Maximum value of the range.</summary>
public T Maximum { get; set; }
/// <summary>Presents the Range in readable format.</summary>
/// <returns>String representation of the Range</returns>
public override string ToString()
{
return string.Format("{0},{1}", this.Minimum, this.Maximum);
}
/// <summary>Determines if the range is valid.</summary>
/// <returns>True if range is valid, else false</returns>
public bool IsValid()
{
return this.Minimum.CompareTo(this.Maximum) <= 0;
}
/// <summary>Determines if the provided value is inside the range.</summary>
/// <param name="value">The value to test</param>
/// <returns>True if the value is inside Range, else false</returns>
public bool ContainsValue(T value)
{
return (this.Minimum.CompareTo(value) <= 0) && (value.CompareTo(this.Maximum) <= 0);
}
/// <summary>Determines if this Range is inside the bounds of another range.</summary>
/// <param name="Range">The parent range to test on</param>
/// <returns>True if range is inclusive, else false</returns>
public bool IsInsideRange(Range<T> range)
{
return this.IsValid() && range.IsValid() && range.ContainsValue(this.Minimum) && range.ContainsValue(this.Maximum);
}
/// <summary>Determines if another range is inside the bounds of this range.</summary>
/// <param name="Range">The child range to test</param>
/// <returns>True if range is inside, else false</returns>
public bool ContainsRange(Range<T> range)
{
return this.IsValid() && range.IsValid() && this.ContainsValue(range.Minimum) && this.ContainsValue(range.Maximum);
}
}
}
@@ -73,12 +73,16 @@ namespace Umbraco.Core.Persistence.Repositories
RelationFactory factory = null;
var relationTypeId = -1;
// the ToList() here is important because we are using _relationTypeRepository and we
// cannot wait until the result is actually enumerated to do so, because that would
// mean we kinda capture the current unit of work and reuse it after it's been disposed
return dtos.Select(x =>
{
if (relationTypeId != x.RelationType)
factory = new RelationFactory(_relationTypeRepository.Get(relationTypeId = x.RelationType));
return DtoToEntity(x, factory);
});
}).ToList();
}
private static IRelation DtoToEntity(RelationDto dto, RelationFactory factory)
@@ -270,12 +270,11 @@ namespace Umbraco.Core.Persistence.Repositories
// once content has been set, "template on disk" are not "on disk" anymore
template.Content = content;
SetVirtualPath(template);
if (dto.Design == content) return;
dto.Design = content;
Database.Update(dto); // though... we don't care about the db value really??!!
SetVirtualPath(template);
}
protected override void PersistDeletedItem(ITemplate entity)
@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IEnumerable<string>))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class CheckboxListValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.CheckBoxListAlias);
}
return false;
}
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
var sourceString = (source ?? string.Empty).ToString();
if (string.IsNullOrEmpty(sourceString))
return Enumerable.Empty<string>();
var values =
sourceString.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim());
return values;
}
}
}
@@ -1,18 +1,28 @@
using Umbraco.Core.Models.PublishedContent;
using System;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(string))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class ColorPickerValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.ColorPickerAlias);
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.ColorPickerAlias);
}
return false;
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
// make sure it's a string
return source.ToString();
return source == null ? string.Empty : source.ToString();
}
}
}
@@ -6,6 +6,7 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(DateTime))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class DatePickerValueConverter : PropertyValueConverterBase
@@ -3,6 +3,7 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(decimal))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class DecimalValueConverter : PropertyValueConverterBase
@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IEnumerable<string>))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class DropdownListMultipleValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.DropDownListMultipleAlias);
}
return false;
}
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
var sourceString = (source ?? "").ToString();
if (string.IsNullOrEmpty(sourceString))
return Enumerable.Empty<string>();
var values =
sourceString.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim());
return values;
}
}
}
@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IEnumerable<int>))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class DropdownListMultipleWithKeysValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.DropdownlistMultiplePublishKeysAlias);
}
return false;
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
if (source == null)
return new int[] { };
var prevalueIds = source.ToString()
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(p => p.Trim())
.Select(int.Parse)
.ToArray();
return prevalueIds;
}
}
}
@@ -0,0 +1,28 @@
using System;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(string))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class DropdownListValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.DropDownListAlias);
}
return false;
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
return source == null ? string.Empty : source.ToString();
}
}
}
@@ -0,0 +1,31 @@
using System;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(int))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class DropdownListWithKeysValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.DropdownlistPublishingKeysAlias);
}
return false;
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
var intAttempt = source.TryConvertTo<int>();
if (intAttempt.Success)
return intAttempt.Result;
return null;
}
}
}
@@ -0,0 +1,27 @@
using System;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(string))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class EmailAddressValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.EmailAddressAlias);
}
return false;
}
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
return source.ToString();
}
}
}
@@ -2,6 +2,7 @@
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(int))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class IntegerValueConverter : PropertyValueConverterBase
@@ -4,6 +4,7 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IHtmlString))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class MarkdownEditorValueConverter : PropertyValueConverterBase
@@ -0,0 +1,27 @@
using System;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(string))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class MemberGroupPickerValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.MemberGroupPickerAlias);
}
return false;
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
return source == null ? string.Empty : source.ToString();
}
}
}
@@ -8,6 +8,7 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IEnumerable<string>))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class MultipleTextStringValueConverter : PropertyValueConverterBase
@@ -0,0 +1,31 @@
using System;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(int))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class RadioButtonListValueConverter : PropertyValueConverterBase
{
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.RadioButtonListAlias);
}
return false;
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
var intAttempt = source.TryConvertTo<int>();
if (intAttempt.Success)
return intAttempt.Result;
return null;
}
}
}
@@ -0,0 +1,100 @@
using System;
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Services;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
public class SliderValueConverter : PropertyValueConverterBase, IPropertyValueConverterMeta
{
private readonly IDataTypeService _dataTypeService;
//TODO: Remove this ctor in v8 since the other one will use IoC
public SliderValueConverter()
: this(ApplicationContext.Current.Services.DataTypeService)
{
}
public SliderValueConverter(IDataTypeService dataTypeService)
{
if (dataTypeService == null) throw new ArgumentNullException("dataTypeService");
_dataTypeService = dataTypeService;
}
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.SliderAlias);
}
return false;
}
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
if (source == null)
{
return null;
}
if (IsRangeDataType(propertyType.DataTypeId))
{
var rangeRawValues = source.ToString().Split(',');
var minimumAttempt = rangeRawValues[0].TryConvertTo<decimal>();
var maximumAttempt = rangeRawValues[1].TryConvertTo<decimal>();
if (minimumAttempt.Success && maximumAttempt.Success)
{
return new Range<decimal>() { Maximum = maximumAttempt.Result, Minimum = minimumAttempt.Result };
}
}
var valueAttempt = source.ToString().TryConvertTo<decimal>();
if (valueAttempt.Success)
{
return valueAttempt.Result;
}
// Something failed in the conversion of the strings to decimals
return null;
}
public Type GetPropertyValueType(PublishedPropertyType propertyType)
{
if (IsRangeDataType(propertyType.DataTypeId))
{
return typeof(Range<decimal>);
}
return typeof(decimal);
}
public PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType, PropertyCacheValue cacheValue)
{
return PropertyCacheLevel.Content;
}
/// <summary>
/// Discovers if the slider is set to range mode.
/// </summary>
/// <param name="dataTypeId">
/// The data type id.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
private bool IsRangeDataType(int dataTypeId)
{
// ** This must be cached (U4-8862) **
var enableRange =
_dataTypeService.GetPreValuesCollectionByDataTypeId(dataTypeId)
.PreValuesAsDictionary.FirstOrDefault(
x => string.Equals(x.Key, "enableRange", StringComparison.InvariantCultureIgnoreCase)).Value;
return enableRange != null && enableRange.Value.TryConvertTo<bool>().Result;
}
}
}
@@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Services;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IEnumerable<string>))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class TagsValueConverter : PropertyValueConverterBase
{
private readonly IDataTypeService _dataTypeService;
//TODO: Remove this ctor in v8 since the other one will use IoC
public TagsValueConverter()
: this(ApplicationContext.Current.Services.DataTypeService)
{
}
public TagsValueConverter(IDataTypeService dataTypeService)
{
if (dataTypeService == null) throw new ArgumentNullException("dataTypeService");
_dataTypeService = dataTypeService;
}
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.TagsAlias);
}
return false;
}
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
// if Json storage type deserialzie and return as string array
if (JsonStorageType(propertyType.DataTypeId))
{
var jArray = JsonConvert.DeserializeObject<JArray>(source.ToString());
return jArray.ToObject<string[]>();
}
// Otherwise assume CSV storage type and return as string array
var csvTags =
source.ToString()
.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.ToArray();
return csvTags;
}
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
if (source == null)
{
return null;
}
return (string[]) source;
}
/// <summary>
/// Discovers if the tags data type is storing its data in a Json format
/// </summary>
/// <param name="dataTypeId">
/// The data type id.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
private bool JsonStorageType(int dataTypeId)
{
// ** This must be cached (U4-8862) **
var storageType =
_dataTypeService.GetPreValuesCollectionByDataTypeId(dataTypeId)
.PreValuesAsDictionary.FirstOrDefault(
x => string.Equals(x.Key, "storageType", StringComparison.InvariantCultureIgnoreCase)).Value;
if (storageType.Value.InvariantEquals("Json"))
{
return true;
}
return false;
}
}
}
@@ -6,11 +6,12 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(string))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class TextStringValueConverter : PropertyValueConverterBase
{
private readonly static string[] PropertyTypeAliases =
private static readonly string[] PropertyTypeAliases =
{
Constants.PropertyEditors.TextboxAlias,
Constants.PropertyEditors.TextboxMultipleAlias
@@ -4,10 +4,11 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
/// <summary>
/// Value converter for the RTE so that it always returns IHtmlString so that Html.Raw doesn't have to be used.
/// </summary>
/// <summary>
/// Value converter for the RTE so that it always returns IHtmlString so that Html.Raw doesn't have to be used.
/// </summary>
// PropertyCacheLevel.Content is ok here because that version of RTE converter does not parse {locallink} nor executes macros
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(IHtmlString))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class TinyMceValueConverter : PropertyValueConverterBase
@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
/// <summary>
/// The upload property value converter.
/// </summary>
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(string))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class UploadPropertyConverter : PropertyValueConverterBase
{
/// <summary>
/// Checks if this converter can convert the property editor and registers if it can.
/// </summary>
/// <param name="propertyType">
/// The published property type.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
public override bool IsConverter(PublishedPropertyType propertyType)
{
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
{
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.UploadFieldAlias);
}
return false;
}
/// <summary>
/// Convert the source object to a string
/// </summary>
/// <param name="propertyType">
/// The published property type.
/// </param>
/// <param name="source">
/// The value of the property
/// </param>
/// <param name="preview">
/// The preview.
/// </param>
/// <returns>
/// The <see cref="object"/>.
/// </returns>
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
return (source ?? "").ToString();
}
}
}
@@ -3,6 +3,7 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
[DefaultPropertyValueConverter]
[PropertyValueType(typeof(bool))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
public class YesNoValueConverter : PropertyValueConverterBase
+18 -3
View File
@@ -1,6 +1,7 @@
using System;
using System.Data;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Events;
using Umbraco.Core.IO;
using Umbraco.Core.Persistence;
@@ -341,7 +342,11 @@ namespace Umbraco.Core.Scoping
{
// if child did not complete we cannot complete
if (completed.HasValue == false || completed.Value == false)
{
if (LogUncompletedScopes)
Logging.LogHelper.Debug<Scope>("Uncompleted Child Scope at\r\n" + Environment.StackTrace);
_completed = false;
}
}
private void EnsureNotDisposed()
@@ -368,13 +373,13 @@ namespace Umbraco.Core.Scoping
#endif
}
var parent = ParentScope;
_scopeProvider.AmbientScope = parent;
#if DEBUG_SCOPES
_scopeProvider.Disposed(this);
#endif
var parent = ParentScope;
_scopeProvider.AmbientScope = parent;
if (parent != null)
parent.ChildCompleted(_completed);
else
@@ -493,5 +498,15 @@ namespace Umbraco.Core.Scoping
TryFinally(index + 1, actions);
}
}
// backing field for LogUncompletedScopes
private static bool? _logUncompletedScopes;
// caching config
// true if Umbraco.CoreDebug.LogUncompletedScope appSetting is set to "true"
private static bool LogUncompletedScopes
{
get { return (_logUncompletedScopes ?? (_logUncompletedScopes = UmbracoConfig.For.CoreDebug().LogUncompletedScopes)).Value; }
}
}
}
+38 -9
View File
@@ -3,6 +3,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Web;
using Umbraco.Core.Events;
using Umbraco.Core.Persistence;
@@ -99,18 +100,23 @@ namespace Umbraco.Core.Scoping
where T : class
{
var objectKey = CallContext.LogicalGetData(key).AsGuid();
if (objectKey == Guid.Empty) return null;
lock (StaticCallContextObjectsLock)
{
object callContextObject;
if (StaticCallContextObjects.TryGetValue(objectKey, out callContextObject))
{
#if DEBUG_SCOPES
//Logging.LogHelper.Debug<ScopeProvider>("GotObject " + objectKey.ToString("N").Substring(0, 8));
Logging.LogHelper.Debug<ScopeProvider>("Got " + typeof(T).Name + " Object " + objectKey.ToString("N").Substring(0, 8));
//Logging.LogHelper.Debug<ScopeProvider>("At:\r\n" + Head(Environment.StackTrace, 24));
#endif
return (T) callContextObject;
}
Logging.LogHelper.Warn<ScopeProvider>("Missed " + typeof(T).Name + " Object " + objectKey.ToString("N").Substring(0, 8));
#if DEBUG_SCOPES
//Logging.LogHelper.Debug<ScopeProvider>("MissedObject " + objectKey.ToString("N").Substring(0, 8));
//Logging.LogHelper.Debug<ScopeProvider>("At:\r\n" + Head(Environment.StackTrace, 24));
#endif
return null;
}
@@ -146,7 +152,8 @@ namespace Umbraco.Core.Scoping
lock (StaticCallContextObjectsLock)
{
#if DEBUG_SCOPES
//Logging.LogHelper.Debug<ScopeProvider>("RemoveObject " + objectKey.ToString("N").Substring(0, 8));
Logging.LogHelper.Debug<ScopeProvider>("Remove Object " + objectKey.ToString("N").Substring(0, 8));
//Logging.LogHelper.Debug<ScopeProvider>("At:\r\n" + Head(Environment.StackTrace, 24));
#endif
StaticCallContextObjects.Remove(objectKey);
}
@@ -160,7 +167,8 @@ namespace Umbraco.Core.Scoping
lock (StaticCallContextObjectsLock)
{
#if DEBUG_SCOPES
//Logging.LogHelper.Debug<ScopeProvider>("AddObject " + objectKey.ToString("N").Substring(0, 8));
Logging.LogHelper.Debug<ScopeProvider>("AddObject " + objectKey.ToString("N").Substring(0, 8));
//Logging.LogHelper.Debug<ScopeProvider>("At:\r\n" + Head(Environment.StackTrace, 24));
#endif
StaticCallContextObjects.Add(objectKey, value);
}
@@ -507,7 +515,7 @@ namespace Umbraco.Core.Scoping
lock (StaticScopeInfosLock)
{
if (StaticScopeInfos.ContainsKey(scope)) throw new Exception("oops: already registered.");
//Logging.LogHelper.Debug<ScopeProvider>("Register " + scope.InstanceId.ToString("N").Substring(0, 8));
Logging.LogHelper.Debug<ScopeProvider>("Register " + scope.InstanceId.ToString("N").Substring(0, 8));
StaticScopeInfos[scope] = new ScopeInfo(scope, Environment.StackTrace);
}
}
@@ -525,14 +533,35 @@ namespace Umbraco.Core.Scoping
if (context == null) return;
throw new Exception("oops: unregistered scope.");
}
//Logging.LogHelper.Debug<ScopeProvider>("Register context " + (context ?? "null") + " for " + scope.InstanceId.ToString("N").Substring(0, 8));
var sb = new StringBuilder();
var s = scope;
while (s != null)
{
if (sb.Length > 0) sb.Append(" < ");
sb.Append(s.InstanceId.ToString("N").Substring(0, 8));
var ss = s as IScopeInternal;
s = ss == null ? null : ss.ParentScope;
}
Logging.LogHelper.Debug<ScopeProvider>("Register " + (context ?? "null") + " context " + sb);
if (context == null) info.NullStack = Environment.StackTrace;
//if (context == null)
// Logging.LogHelper.Debug<ScopeProvider>("STACK\r\n" + info.NullStack);
//Logging.LogHelper.Debug<ScopeProvider>("At:\r\n" + Head(Environment.StackTrace, 16));
info.Context = context;
}
}
private static string Head(string s, int count)
{
var pos = 0;
var i = 0;
while (i < count && pos >= 0)
{
pos = s.IndexOf("\r\n", pos + 1, StringComparison.OrdinalIgnoreCase);
i++;
}
if (pos < 0) return s;
return s.Substring(0, pos);
}
public void Disposed(IScope scope)
{
lock (StaticScopeInfosLock)
@@ -542,7 +571,7 @@ namespace Umbraco.Core.Scoping
// enable this by default
//Console.WriteLine("unregister " + scope.InstanceId.ToString("N").Substring(0, 8));
StaticScopeInfos.Remove(scope);
//Logging.LogHelper.Debug<ScopeProvider>("Remove " + scope.InstanceId.ToString("N").Substring(0, 8));
Logging.LogHelper.Debug<ScopeProvider>("Remove " + scope.InstanceId.ToString("N").Substring(0, 8));
// instead, enable this to keep *all* scopes
// beware, there can be a lot of scopes!
+3 -5
View File
@@ -573,11 +573,9 @@ namespace Umbraco.Core.Services
var repository = RepositoryFactory.CreateContentRepository(uow);
var query = Query<IContent>.Builder;
//if the id is System Root, then just get all
if (id != Constants.System.Root)
{
query.Where(x => x.ParentId == id);
}
// always check for a parent - else it will also get decendants (and then you should use the GetPagedDescendants method)
query.Where(x => x.ParentId == id);
IQuery<IContent> filterQuery = null;
if (filter.IsNullOrWhiteSpace() == false)
{
+3 -5
View File
@@ -450,11 +450,9 @@ namespace Umbraco.Core.Services
var repository = RepositoryFactory.CreateMediaRepository(uow);
var query = Query<IMedia>.Builder;
//if the id is System Root, then just get all
if (id != Constants.System.Root)
{
query.Where(x => x.ParentId == id);
}
// always check for a parent - else it will also get decendants (and then you should use the GetPagedDescendants method)
query.Where(x => x.ParentId == id);
IQuery<IMedia> filterQuery = null;
if (filter.IsNullOrWhiteSpace() == false)
{
+40 -5
View File
@@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Umbraco.Core</RootNamespace>
<AssemblyName>Umbraco.Core</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
@@ -39,15 +39,19 @@
<ItemGroup>
<Reference Include="AutoMapper, Version=3.3.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="AutoMapper.Net4, Version=3.3.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="HtmlAgilityPack, Version=1.4.9.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
<HintPath>..\packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll</HintPath>
<Reference Include="HtmlAgilityPack, Version=1.4.9.5, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
<HintPath>..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ImageProcessor, Version=2.5.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.2.5.2\lib\net45\ImageProcessor.dll</HintPath>
@@ -55,49 +59,64 @@
</Reference>
<Reference Include="log4net, Version=1.2.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.5\lib\net45-full\log4net.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.AspNet.Identity.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.AspNet.Identity.Owin, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Identity.Owin.2.2.1\lib\net45\Microsoft.AspNet.Identity.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Security, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Security.Cookies, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Security.Cookies.3.0.1\lib\net45\Microsoft.Owin.Security.Cookies.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.Security.OAuth, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.Security.OAuth.3.0.1\lib\net45\Microsoft.Owin.Security.OAuth.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="MiniProfiler, Version=2.1.0.0, Culture=neutral, PublicKeyToken=b44f9351044011a3, processorArchitecture=MSIL">
<HintPath>..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
<HintPath>..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Semver.2.0.4\lib\net452\Semver.dll</HintPath>
<HintPath>..\packages\Semver.2.0.4\lib\netstandard1.1\Semver.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data.Entity" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.DirectoryServices.AccountManagement" />
<Reference Include="System.Drawing" />
@@ -199,6 +218,7 @@
<Compile Include="Configuration\Dashboard\SectionElement.cs" />
<Compile Include="Configuration\Dashboard\TabCollection.cs" />
<Compile Include="Configuration\Dashboard\TabElement.cs" />
<Compile Include="Configuration\CoreDebug.cs" />
<Compile Include="Configuration\FileSystemProviderElement.cs" />
<Compile Include="Configuration\FileSystemProviderElementCollection.cs" />
<Compile Include="Configuration\FileSystemProvidersSection.cs" />
@@ -311,12 +331,14 @@
<Compile Include="Deploy\ArtifactSignature.cs" />
<Compile Include="Deploy\Difference.cs" />
<Compile Include="Deploy\Direction.cs" />
<Compile Include="Deploy\IFileStore.cs" />
<Compile Include="Deploy\IFileType.cs" />
<Compile Include="Deploy\IFileTypeCollection.cs" />
<Compile Include="Events\EventDefinitionFilter.cs" />
<Compile Include="Events\IDeletingMediaFilesEventArgs.cs" />
<Compile Include="Events\ScopeEventDispatcherBase.cs" />
<Compile Include="Events\ScopeLifespanMessagesFactory.cs" />
<Compile Include="IHttpContextAccessor.cs" />
<Compile Include="Models\PublishedContent\PublishedContentTypeConverter.cs" />
<Compile Include="OrderedHashSet.cs" />
<Compile Include="Events\UninstallPackageEventArgs.cs" />
<Compile Include="Models\GridValue.cs" />
@@ -425,9 +447,11 @@
<Compile Include="Models\PartialViewType.cs" />
<Compile Include="Models\PublicAccessEntry.cs" />
<Compile Include="Models\PublicAccessRule.cs" />
<Compile Include="Models\PublishedContent\PublishedContentEnumerable.cs" />
<Compile Include="Models\PublishedContent\PublishedContentWithKeyExtended.cs" />
<Compile Include="Models\PublishedContent\PublishedContentWithKeyModel.cs" />
<Compile Include="Models\PublishedContent\PublishedContentWithKeyWrapped.cs" />
<Compile Include="Models\Range.cs" />
<Compile Include="Models\Rdbms\AccessDto.cs" />
<Compile Include="Media\Exif\BitConverterEx.cs" />
<Compile Include="Media\Exif\ExifBitConverter.cs" />
@@ -558,10 +582,21 @@
<Compile Include="Persistence\UnitOfWork\ScopeUnitOfWorkProvider.cs" />
<Compile Include="PropertyEditors\DecimalValidator.cs" />
<Compile Include="PropertyEditors\PropertyEditorValueTypes.cs" />
<Compile Include="PropertyEditors\ValueConverters\CheckboxListValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\DropdownListMultipleValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\DropdownListMultipleWithKeysValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\DropdownListValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\DropdownListWithKeysValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\EmailAddressValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\GridValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\DecimalValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\LabelValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\ImageCropperValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\MemberGroupPickerValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\RadioButtonListValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\SliderValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\TagsValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\UploadPropertyConverter.cs" />
<Compile Include="Publishing\UnPublishedStatusType.cs" />
<Compile Include="Publishing\UnPublishStatus.cs" />
<Compile Include="SafeCallContext.cs" />
+6 -1
View File
@@ -32,4 +32,9 @@
</dependentAssembly>
</assemblyBinding>
</runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" /></startup></configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /></startup><system.data>
<DbProviderFactories>
<remove invariant="MySql.Data.MySqlClient" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>
</system.data></configuration>
+7 -3
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AutoMapper" version="3.3.1" targetFramework="net45" />
<package id="HtmlAgilityPack" version="1.4.9" targetFramework="net45" />
<package id="HtmlAgilityPack" version="1.4.9.5" targetFramework="net45" />
<package id="ImageProcessor" version="2.5.2" targetFramework="net45" />
<package id="log4net" version="2.0.5" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net45" />
@@ -12,9 +12,13 @@
<package id="Microsoft.Owin.Security.OAuth" version="3.0.1" targetFramework="net45" />
<package id="MiniProfiler" version="2.1.0" targetFramework="net45" />
<package id="MySql.Data" version="6.9.8" targetFramework="net45" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net462" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<package id="Semver" version="2.0.4" targetFramework="net462" />
<package id="Semver" version="2.0.4" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
<package id="SqlServerCE" version="4.0.0.1" targetFramework="net45" />
<package id="System.Runtime" version="4.1.0" targetFramework="net45" />
<package id="System.Runtime.Extensions" version="4.1.0" targetFramework="net45" />
<package id="System.Runtime.InteropServices" version="4.1.0" targetFramework="net45" />
<package id="System.Text.RegularExpressions" version="4.1.0" targetFramework="net45" />
</packages>
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
@@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Umbraco.Tests.Benchmarks</RootNamespace>
<AssemblyName>Umbraco.Tests.Benchmarks</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
@@ -40,101 +40,55 @@
<ItemGroup>
<Reference Include="BenchmarkDotNet, Version=0.9.9.0, Culture=neutral, PublicKeyToken=aa0ca2f9092cefc4, processorArchitecture=MSIL">
<HintPath>..\packages\BenchmarkDotNet.0.9.9\lib\net45\BenchmarkDotNet.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="BenchmarkDotNet.Core, Version=0.9.9.0, Culture=neutral, PublicKeyToken=aa0ca2f9092cefc4, processorArchitecture=MSIL">
<HintPath>..\packages\BenchmarkDotNet.Core.0.9.9\lib\net45\BenchmarkDotNet.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="BenchmarkDotNet.Diagnostics.Windows, Version=0.9.9.0, Culture=neutral, PublicKeyToken=aa0ca2f9092cefc4, processorArchitecture=MSIL">
<HintPath>..\packages\BenchmarkDotNet.Diagnostics.Windows.0.9.9\lib\net45\BenchmarkDotNet.Diagnostics.Windows.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="BenchmarkDotNet.Toolchains.Roslyn, Version=0.9.9.0, Culture=neutral, PublicKeyToken=aa0ca2f9092cefc4, processorArchitecture=MSIL">
<HintPath>..\packages\BenchmarkDotNet.Toolchains.Roslyn.0.9.9\lib\net45\BenchmarkDotNet.Toolchains.Roslyn.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CodeAnalysis, Version=1.3.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CodeAnalysis.CSharp, Version=1.3.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.CSharp.1.3.2\lib\net45\Microsoft.CodeAnalysis.CSharp.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Diagnostics.Tracing.TraceEvent, Version=1.0.41.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.41\lib\net40\Microsoft.Diagnostics.Tracing.TraceEvent.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.AppContext, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.AppContext.4.1.0\lib\net46\System.AppContext.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Collections.Immutable, Version=1.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Console, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Console.4.0.0\lib\net46\System.Console.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
</Reference>
<Reference Include="System.Diagnostics.FileVersionInfo, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Diagnostics.FileVersionInfo.4.0.0\lib\net46\System.Diagnostics.FileVersionInfo.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Diagnostics.StackTrace, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Diagnostics.StackTrace.4.0.1\lib\net46\System.Diagnostics.StackTrace.dll</HintPath>
</Reference>
<Reference Include="System.IO.FileSystem, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.FileSystem.4.0.1\lib\net46\System.IO.FileSystem.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.IO.FileSystem.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.IO.FileSystem.Primitives.4.0.1\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Management" />
<Reference Include="System.Numerics" />
<Reference Include="System.Reflection, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Reflection.4.1.0\lib\net462\System.Reflection.dll</HintPath>
</Reference>
<Reference Include="System.Reflection.Metadata, Version=1.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Reflection.Metadata.1.3.0\lib\portable-net45+win8\System.Reflection.Metadata.dll</HintPath>
</Reference>
<Reference Include="System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.4.1.0\lib\net462\System.Runtime.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Extensions, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.Extensions.4.1.0\lib\net462\System.Runtime.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.InteropServices, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.InteropServices.4.1.0\lib\net462\System.Runtime.InteropServices.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Algorithms, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.Algorithms.4.2.0\lib\net461\System.Security.Cryptography.Algorithms.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Encoding, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.Encoding.4.0.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Cryptography.Primitives, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.Primitives.4.0.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.1.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
</Reference>
<Reference Include="System.Text.Encoding.CodePages, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Encoding.CodePages.4.0.1\lib\net46\System.Text.Encoding.CodePages.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.0.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Thread, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Thread.4.0.0\lib\net46\System.Threading.Thread.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
@@ -143,18 +97,6 @@
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.XmlDocument, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Xml.XmlDocument.4.0.1\lib\net46\System.Xml.XmlDocument.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.XPath, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Xml.XPath.4.0.1\lib\net46\System.Xml.XPath.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.XPath.XDocument, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Xml.XPath.XDocument.4.0.1\lib\net46\System.Xml.XPath.XDocument.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="LinqCastBenchmarks.cs" />
@@ -168,6 +110,7 @@
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
<None Include="_TraceEventProgrammersGuide.docx" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Umbraco.Core\Umbraco.Core.csproj">
@@ -187,6 +130,10 @@
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll" />
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" />
</ItemGroup>
<ItemGroup>
<Content Include="TraceEvent.ReadMe.txt" />
<Content Include="TraceEvent.ReleaseNotes.txt" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
+24 -40
View File
@@ -10,45 +10,29 @@
<package id="Microsoft.Diagnostics.Tracing.TraceEvent" version="1.0.41" targetFramework="net45" />
<package id="Microsoft.SqlServer.Compact" version="4.0.8854.1" targetFramework="net45" />
<package id="SqlServerCE" version="4.0.0.1" targetFramework="net45" />
<package id="System.AppContext" version="4.1.0" targetFramework="net462" />
<package id="System.Collections" version="4.0.11" targetFramework="net462" />
<package id="System.Collections.Concurrent" version="4.0.12" targetFramework="net462" />
<package id="System.Collections.Immutable" version="1.2.0" targetFramework="net462" />
<package id="System.Console" version="4.0.0" targetFramework="net462" />
<package id="System.Diagnostics.Debug" version="4.0.11" targetFramework="net462" />
<package id="System.Diagnostics.FileVersionInfo" version="4.0.0" targetFramework="net462" />
<package id="System.Diagnostics.StackTrace" version="4.0.1" targetFramework="net462" />
<package id="System.Diagnostics.Tools" version="4.0.1" targetFramework="net462" />
<package id="System.Dynamic.Runtime" version="4.0.11" targetFramework="net462" />
<package id="System.Globalization" version="4.0.11" targetFramework="net462" />
<package id="System.IO.FileSystem" version="4.0.1" targetFramework="net462" />
<package id="System.IO.FileSystem.Primitives" version="4.0.1" targetFramework="net462" />
<package id="System.Linq" version="4.1.0" targetFramework="net462" />
<package id="System.Linq.Expressions" version="4.1.0" targetFramework="net462" />
<package id="System.Reflection" version="4.1.0" targetFramework="net462" />
<package id="System.Reflection.Metadata" version="1.3.0" targetFramework="net462" />
<package id="System.Reflection.Primitives" version="4.0.1" targetFramework="net462" />
<package id="System.Resources.ResourceManager" version="4.0.1" targetFramework="net462" />
<package id="System.Runtime" version="4.1.0" targetFramework="net462" />
<package id="System.Runtime.Extensions" version="4.1.0" targetFramework="net462" />
<package id="System.Runtime.Handles" version="4.0.1" targetFramework="net462" />
<package id="System.Runtime.InteropServices" version="4.1.0" targetFramework="net462" />
<package id="System.Runtime.Numerics" version="4.0.1" targetFramework="net462" />
<package id="System.Security.Cryptography.Algorithms" version="4.2.0" targetFramework="net462" />
<package id="System.Security.Cryptography.Encoding" version="4.0.0" targetFramework="net462" />
<package id="System.Security.Cryptography.Primitives" version="4.0.0" targetFramework="net462" />
<package id="System.Security.Cryptography.X509Certificates" version="4.1.0" targetFramework="net462" />
<package id="System.Text.Encoding" version="4.0.11" targetFramework="net462" />
<package id="System.Text.Encoding.CodePages" version="4.0.1" targetFramework="net462" />
<package id="System.Text.Encoding.Extensions" version="4.0.11" targetFramework="net462" />
<package id="System.Threading" version="4.0.11" targetFramework="net462" />
<package id="System.Threading.Tasks" version="4.0.11" targetFramework="net462" />
<package id="System.Collections" version="4.0.11" targetFramework="net45" />
<package id="System.Collections.Concurrent" version="4.0.12" targetFramework="net45" />
<package id="System.Collections.Immutable" version="1.2.0" targetFramework="net45" />
<package id="System.Diagnostics.Debug" version="4.0.11" targetFramework="net45" />
<package id="System.Diagnostics.Tools" version="4.0.1" targetFramework="net45" />
<package id="System.Dynamic.Runtime" version="4.0.11" targetFramework="net45" />
<package id="System.Globalization" version="4.0.11" targetFramework="net45" />
<package id="System.Linq" version="4.1.0" targetFramework="net45" />
<package id="System.Linq.Expressions" version="4.1.0" targetFramework="net45" />
<package id="System.Reflection" version="4.1.0" targetFramework="net45" />
<package id="System.Reflection.Metadata" version="1.3.0" targetFramework="net45" />
<package id="System.Reflection.Primitives" version="4.0.1" targetFramework="net45" />
<package id="System.Resources.ResourceManager" version="4.0.1" targetFramework="net45" />
<package id="System.Runtime" version="4.1.0" targetFramework="net45" />
<package id="System.Runtime.Extensions" version="4.1.0" targetFramework="net45" />
<package id="System.Runtime.InteropServices" version="4.1.0" targetFramework="net45" />
<package id="System.Runtime.Numerics" version="4.0.1" targetFramework="net45" />
<package id="System.Text.Encoding" version="4.0.11" targetFramework="net45" />
<package id="System.Text.Encoding.Extensions" version="4.0.11" targetFramework="net45" />
<package id="System.Threading" version="4.0.11" targetFramework="net45" />
<package id="System.Threading.Tasks" version="4.0.11" targetFramework="net45" />
<package id="System.Threading.Tasks.Extensions" version="4.0.0" targetFramework="net45" />
<package id="System.Threading.Tasks.Parallel" version="4.0.1" targetFramework="net462" />
<package id="System.Threading.Thread" version="4.0.0" targetFramework="net462" />
<package id="System.Xml.ReaderWriter" version="4.0.11" targetFramework="net462" />
<package id="System.Xml.XDocument" version="4.0.11" targetFramework="net462" />
<package id="System.Xml.XmlDocument" version="4.0.1" targetFramework="net462" />
<package id="System.Xml.XPath" version="4.0.1" targetFramework="net462" />
<package id="System.Xml.XPath.XDocument" version="4.0.1" targetFramework="net462" />
<package id="System.Threading.Tasks.Parallel" version="4.0.1" targetFramework="net45" />
<package id="System.Xml.ReaderWriter" version="4.0.11" targetFramework="net45" />
<package id="System.Xml.XDocument" version="4.0.11" targetFramework="net45" />
</packages>
+1 -1
View File
@@ -91,7 +91,7 @@
</siteMap>
</system.web>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" /></startup>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /></startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
@@ -23,6 +23,17 @@ namespace Umbraco.Tests.IO
// media fs wants this
ApplicationContext.Current = new ApplicationContext(CacheHelper.CreateDisabledCacheHelper(), new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()));
// start clean
// because some tests will create corrupt or weird filesystems
FileSystemProviderManager.Current.Reset();
}
[TearDown]
public void TearDown()
{
// stay clean (see note in SetUp)
FileSystemProviderManager.Current.Reset();
}
[Test]
@@ -66,22 +77,52 @@ namespace Umbraco.Tests.IO
Assert.IsTrue(Directory.Exists(physPath));
}
public void Singleton_Typed_File_System()
{
var fs1 = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
var fs2 = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
Assert.AreSame(fs1, fs2);
}
[Test]
public void Exception_Thrown_On_Invalid_Typed_File_System()
{
Assert.Throws<InvalidOperationException>(() => FileSystemProviderManager.Current.GetFileSystemProvider<InvalidTypedFileSystem>());
}
/// <summary>
/// Used in unit tests, for a typed file system we need to inherit from FileSystemWrapper and they MUST have a ctor
/// that only accepts a base IFileSystem object
/// </summary>
internal class InvalidTypedFileSystem : FileSystemWrapper
[Test]
public void Exception_Thrown_On_NonConfigured_Typed_File_System()
{
// note: we need to reset the manager between tests else the Accept_Fallback test would corrupt that one
Assert.Throws<ArgumentException>(() => FileSystemProviderManager.Current.GetFileSystemProvider<NonConfiguredTypeFileSystem>());
}
[Test]
public void Accept_Fallback_On_NonConfigured_Typed_File_System()
{
var fs = FileSystemProviderManager.Current.GetFileSystemProvider<NonConfiguredTypeFileSystem>(() => new PhysicalFileSystem("~/App_Data/foo"));
Assert.NotNull(fs);
}
/// <summary>
/// Used in unit tests, for a typed file system we need to inherit from FileSystemWrapper and they MUST have a ctor
/// that only accepts a base IFileSystem object
/// </summary>
internal class InvalidTypedFileSystem : FileSystemWrapper
{
public InvalidTypedFileSystem(IFileSystem wrapped, string invalidParam) : base(wrapped)
{
}
public InvalidTypedFileSystem(IFileSystem wrapped, string invalidParam)
: base(wrapped)
{ }
}
[FileSystemProvider("noconfig")]
internal class NonConfiguredTypeFileSystem : FileSystemWrapper
{
public NonConfiguredTypeFileSystem(IFileSystem wrapped)
: base(wrapped)
{ }
}
}
}
+22 -19
View File
@@ -377,13 +377,14 @@ namespace Umbraco.Tests.IO
var path = IOHelper.MapPath("FileSysTests");
var appdata = IOHelper.MapPath("App_Data");
Directory.CreateDirectory(path);
Directory.CreateDirectory(appdata);
var scopedFileSystems = false;
var scopeProvider = MockScopeProvider(() => scopedFileSystems);
var fs = new PhysicalFileSystem(path, "ignore");
var sw = new ShadowWrapper(fs, "shadow", scopeProvider);
var swa = new[] {sw};
var swa = new[] { sw };
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
sw.AddFile("sub/f1.txt", ms);
@@ -393,47 +394,47 @@ namespace Umbraco.Tests.IO
// explicit shadow without scope does not work
sw.Shadow(id = Guid.NewGuid());
Assert.IsTrue(Directory.Exists(appdata + "/Shadow/" + id));
Assert.IsTrue(Directory.Exists(appdata + "/TEMP/ShadowFs/" + id));
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
sw.AddFile("sub/f2.txt", ms);
Assert.IsTrue(fs.FileExists("sub/f2.txt"));
sw.UnShadow(true);
Assert.IsTrue(fs.FileExists("sub/f2.txt"));
Assert.IsFalse(Directory.Exists(appdata + "/Shadow/" + id));
Assert.IsFalse(Directory.Exists(appdata + "/TEMP/ShadowFs/" + id));
// shadow with scope but no complete does not complete
scopedFileSystems = true; // pretend we have a scope
var scope = new ShadowFileSystems(id = Guid.NewGuid(), swa);
Assert.IsTrue(Directory.Exists(appdata + "/Shadow/" + id));
Assert.IsTrue(Directory.Exists(appdata + "/TEMP/ShadowFs/" + id));
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
sw.AddFile("sub/f3.txt", ms);
Assert.IsFalse(fs.FileExists("sub/f3.txt"));
Assert.AreEqual(1, Directory.GetDirectories(appdata + "/Shadow").Length);
Assert.AreEqual(1, Directory.GetDirectories(appdata + "/TEMP/ShadowFs").Length);
scope.Dispose();
scopedFileSystems = false;
Assert.IsFalse(fs.FileExists("sub/f3.txt"));
Assert.IsFalse(Directory.Exists(appdata + "/Shadow/" + id));
Assert.IsFalse(Directory.Exists(appdata + "/TEMP/ShadowFs/" + id));
// shadow with scope and complete does complete
scopedFileSystems = true; // pretend we have a scope
scope = new ShadowFileSystems(id = Guid.NewGuid(), swa);
Assert.IsTrue(Directory.Exists(appdata + "/Shadow/" + id));
Assert.IsTrue(Directory.Exists(appdata + "/TEMP/ShadowFs/" + id));
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
sw.AddFile("sub/f4.txt", ms);
Assert.IsFalse(fs.FileExists("sub/f4.txt"));
Assert.AreEqual(1, Directory.GetDirectories(appdata + "/Shadow").Length);
Assert.AreEqual(1, Directory.GetDirectories(appdata + "/TEMP/ShadowFs").Length);
scope.Complete();
scope.Dispose();
scopedFileSystems = false;
TestHelper.TryAssert(() => Assert.AreEqual(0, Directory.GetDirectories(appdata + "/Shadow").Length));
TestHelper.TryAssert(() => Assert.AreEqual(0, Directory.GetDirectories(appdata + "/TEMP/ShadowFs").Length));
Assert.IsTrue(fs.FileExists("sub/f4.txt"));
Assert.IsFalse(Directory.Exists(appdata + "/Shadow/" + id));
Assert.IsFalse(Directory.Exists(appdata + "/TEMP/ShadowFs/" + id));
// test scope for "another thread"
scopedFileSystems = true; // pretend we have a scope
scope = new ShadowFileSystems(id = Guid.NewGuid(), swa);
Assert.IsTrue(Directory.Exists(appdata + "/Shadow/" + id));
Assert.IsTrue(Directory.Exists(appdata + "/TEMP/ShadowFs/" + id));
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
sw.AddFile("sub/f5.txt", ms);
Assert.IsFalse(fs.FileExists("sub/f5.txt"));
@@ -449,7 +450,7 @@ namespace Umbraco.Tests.IO
scope.Dispose();
scopedFileSystems = false;
Assert.IsTrue(fs.FileExists("sub/f5.txt"));
Assert.IsFalse(Directory.Exists(appdata + "/Shadow/" + id));
Assert.IsFalse(Directory.Exists(appdata + "/TEMP/ShadowFs/" + id));
}
[Test]
@@ -464,7 +465,7 @@ namespace Umbraco.Tests.IO
var fs = new PhysicalFileSystem(path, "ignore");
var sw = new ShadowWrapper(fs, "shadow", scopeProvider);
var swa = new[] {sw};
var swa = new[] { sw };
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
sw.AddFile("sub/f1.txt", ms);
@@ -474,7 +475,7 @@ namespace Umbraco.Tests.IO
scopedFileSystems = true; // pretend we have a scope
var scope = new ShadowFileSystems(id = Guid.NewGuid(), swa);
Assert.IsTrue(Directory.Exists(appdata + "/Shadow/" + id));
Assert.IsTrue(Directory.Exists(appdata + "/TEMP/ShadowFs/" + id));
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
sw.AddFile("sub/f2.txt", ms);
Assert.IsFalse(fs.FileExists("sub/f2.txt"));
@@ -490,7 +491,7 @@ namespace Umbraco.Tests.IO
scope.Dispose();
scopedFileSystems = false;
Assert.IsTrue(fs.FileExists("sub/f2.txt"));
TestHelper.TryAssert(() => Assert.IsFalse(Directory.Exists(appdata + "/Shadow/" + id)));
TestHelper.TryAssert(() => Assert.IsFalse(Directory.Exists(appdata + "/TEMP/ShadowFs/" + id)));
string text;
using (var s = fs.OpenFile("sub/f2.txt"))
@@ -513,7 +514,7 @@ namespace Umbraco.Tests.IO
var fs = new PhysicalFileSystem(path, "ignore");
var sw = new ShadowWrapper(fs, "shadow", scopeProvider);
var swa = new[] {sw};
var swa = new[] { sw };
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
sw.AddFile("sub/f1.txt", ms);
@@ -523,7 +524,7 @@ namespace Umbraco.Tests.IO
scopedFileSystems = true; // pretend we have a scope
var scope = new ShadowFileSystems(id = Guid.NewGuid(), swa);
Assert.IsTrue(Directory.Exists(appdata + "/Shadow/" + id));
Assert.IsTrue(Directory.Exists(appdata + "/TEMP/ShadowFs/" + id));
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
sw.AddFile("sub/f2.txt", ms);
Assert.IsFalse(fs.FileExists("sub/f2.txt"));
@@ -555,7 +556,7 @@ namespace Umbraco.Tests.IO
var e = ae.InnerExceptions[0];
Assert.IsNotNull(e.InnerException);
Assert.IsInstanceOf<AggregateException>(e);
ae = (AggregateException) e;
ae = (AggregateException)e;
Assert.AreEqual(1, ae.InnerExceptions.Count);
e = ae.InnerExceptions[0];
@@ -651,7 +652,7 @@ namespace Umbraco.Tests.IO
// ensure we get 2 files from the shadow
var getFiles = ss.GetFiles(string.Empty);
Assert.AreEqual(2, getFiles.Count());
var fsFiles = fs.GetFiles(string.Empty).ToArray();
Assert.AreEqual(1, fsFiles.Length);
var sfsFiles = sfs.GetFiles(string.Empty).ToArray();
@@ -805,6 +806,7 @@ namespace Umbraco.Tests.IO
}
[Test]
[Ignore("Does not work on all environments, Directory.GetFiles is broken.")]
public void ShadowGetFilesUsingWildcardAndSingleCharacterFilter()
{
// Arrange
@@ -845,6 +847,7 @@ namespace Umbraco.Tests.IO
}
[Test]
[Ignore("Does not work on all environments, Directory.GetFiles is broken.")]
public void ShadowFileSystemFilterIsAsBrokenAsRealFileSystemFilter()
{
// Arrange
@@ -1,8 +1,7 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.PropertyEditors.ValueConverters;
using Umbraco.Tests.TestHelpers;
namespace Umbraco.Tests.PropertyEditors
{
@@ -58,5 +57,44 @@ namespace Umbraco.Tests.PropertyEditors
Assert.AreEqual(expected, result);
}
}
[TestCase("apples", new[] { "apples" })]
[TestCase("apples,oranges", new[] { "apples", "oranges" })]
[TestCase(" apples, oranges, pears ", new[] { "apples", "oranges", "pears" })]
[TestCase("", new string[] { })]
[TestCase(null, new string[] { })]
public void CanConvertCheckboxListPropertyEditor(object value, IEnumerable<string> expected)
{
var converter = new CheckboxListValueConverter();
var result = converter.ConvertSourceToObject(null, value, false);
Assert.AreEqual(expected, result);
}
[TestCase("apples", new[] {"apples"})]
[TestCase("apples,oranges", new[] {"apples", "oranges"})]
[TestCase("apples , oranges, pears ", new[] {"apples", "oranges", "pears"})]
[TestCase("", new string[] {})]
[TestCase(null, new string[] {})]
public void CanConvertDropdownListMultiplePropertyEditor(object value, IEnumerable<string> expected)
{
var converter = new DropdownListMultipleValueConverter();
var result = converter.ConvertSourceToObject(null, value, false);
Assert.AreEqual(expected, result);
}
[TestCase("100", new[] {100})]
[TestCase("100,200", new[] {100, 200})]
[TestCase("100 , 200, 300 ", new[] {100, 200, 300})]
[TestCase("", new int[] {})]
[TestCase(null, new int[] {})]
public void CanConvertDropdownListMultipleWithKeysPropertyEditor(object value, IEnumerable<int> expected)
{
var converter = new DropdownListMultipleWithKeysValueConverter();
var result = converter.ConvertDataToSource(null, value, false);
Assert.AreEqual(expected, result);
}
}
}
@@ -0,0 +1,177 @@
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using Umbraco.Tests.Logging;
using Umbraco.Web.Scheduling;
namespace Umbraco.Tests.Scheduling
{
[TestFixture]
[Timeout(60000)]
public class BackgroundTaskRunnerTests2
{
// this tests was used to debug a background task runner issue that was unearthed by Deploy,
// where work items would never complete under certain circumstances, due to threading issues.
// (fixed now)
//
[Test]
[Timeout(4000)]
public async Task ThreadResumeIssue()
{
var logger = new ConsoleLogger();
var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, logger);
var work = new ThreadResumeIssueWorkItem();
runner.Add(work);
Console.WriteLine("running");
await Task.Delay(1000); // don't complete too soon
Console.WriteLine("completing");
// this never returned, never reached "completed" because the same thread
// resumed executing the waiting on queue operation in the runner
work.Complete();
Console.WriteLine("completed");
Console.WriteLine("done");
}
public class ThreadResumeIssueWorkItem : IBackgroundTask
{
private TaskCompletionSource<int> _completionSource;
public async Task RunAsync(CancellationToken token)
{
_completionSource = new TaskCompletionSource<int>();
token.Register(() => _completionSource.TrySetCanceled()); // propagate
Console.WriteLine("item running...");
await _completionSource.Task.ConfigureAwait(false);
Console.WriteLine("item returning");
}
public bool Complete(bool success = true)
{
Console.WriteLine("item completing");
// this never returned, see test
_completionSource.SetResult(0);
Console.WriteLine("item returning from completing");
return true;
}
public void Run()
{
throw new NotImplementedException();
}
public bool IsAsync { get { return true; } }
public void Dispose()
{}
}
[Test]
[Ignore("Only runs in the debugger.")]
public async Task DebuggerInterferenceIssue()
{
var logger = new ConsoleLogger();
var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, logger);
var taskCompleted = false;
runner.TaskCompleted += (sender, args) =>
{
Console.WriteLine("runner task completed");
taskCompleted = true;
};
var work = new DebuggerInterferenceIssueWorkitem();
// add the workitem to the runner and wait until it is running
runner.Add(work);
work.Running.Wait();
// then wait a little bit more to ensure that the WhenAny has been entered
await Task.Delay(500);
// then break
// when the timeout triggers, we cannot handle it
// taskCompleted value does *not* change & nothing happens
Debugger.Break();
// release after 15s
// WhenAny should return the timeout task
// and then taskCompleted should turn to true
// = debugging does not prevent task completion
Console.WriteLine("*");
Assert.IsFalse(taskCompleted);
await Task.Delay(1000);
Console.WriteLine("*");
Assert.IsTrue(taskCompleted);
}
public class DebuggerInterferenceIssueWorkitem : IBackgroundTask
{
private readonly SemaphoreSlim _timeout = new SemaphoreSlim(0, 1);
private readonly ManualResetEventSlim _running = new ManualResetEventSlim(false);
private Timer _timer;
public ManualResetEventSlim Running { get { return _running; } }
public async Task RunAsync(CancellationToken token)
{
// timeout timer
_timer = new Timer(_ => { _timeout.Release(); });
_timer.Change(1000, 0);
var timeout = _timeout.WaitAsync(token);
var source = CancellationTokenSource.CreateLinkedTokenSource(token); // cancels when token cancels
_running.Set();
var task = WorkExecuteAsync(source.Token);
Console.WriteLine("execute");
var anyTask = await Task.WhenAny(task, timeout).ConfigureAwait(false);
Console.Write("anyTask: ");
Console.WriteLine(anyTask == timeout ? "timeout" : "task");
Console.WriteLine("return");
}
private async Task WorkExecuteAsync(CancellationToken token)
{
await Task.Delay(30000);
}
public void Run()
{
throw new NotImplementedException();
}
public bool IsAsync { get { return true; } }
public void Dispose()
{ }
}
[Test]
[Ignore("Only runs in the debugger.")]
public void TimerDebuggerTest()
{
var triggered = false;
var timer = new Timer(_ => { triggered = true; });
timer.Change(1000, 0);
Debugger.Break();
// pause in debugger for 10s
// means the timer triggers while execution is suspended
// 'triggered' remains false all along
// then resume execution
// and 'triggered' becomes true, so the trigger "catches up"
// = debugging should not prevent triggered code from executing
Thread.Sleep(200);
Assert.IsTrue(triggered);
}
}
}
@@ -1,73 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using Umbraco.Tests.Logging;
using Umbraco.Web.Scheduling;
namespace Umbraco.Tests.Scheduling
{
// THIS REPRODUCES THE DEPLOY ISSUE IN CORE
//
// the exact same thing also reproduces in playground
// so it's not a framework version issue - but something we're doing here
[TestFixture]
[Timeout(4000)]
public class Repro
{
[Test]
public async Task ReproduceDeployIssue()
{
var logger = new ConsoleLogger();
var runner = new BackgroundTaskRunner<IBackgroundTask>(new BackgroundTaskRunnerOptions { KeepAlive = true, LongRunning = true }, logger);
var work = new SimpleWorkItem();
runner.Add(work);
Console.WriteLine("running");
await Task.Delay(1000); // don't complete too soon
Console.WriteLine("completing");
// this never returns, never reached "completed" because the same thread
// resumes executing the waiting on queue operation in the runner
work.Complete();
Console.WriteLine("completed");
Console.WriteLine("done");
}
public class SimpleWorkItem : IBackgroundTask
{
private TaskCompletionSource<int> _completionSource;
public async Task RunAsync(CancellationToken token)
{
_completionSource = new TaskCompletionSource<int>();
token.Register(() => _completionSource.TrySetCanceled()); // propagate
Console.WriteLine("item running...");
await _completionSource.Task.ConfigureAwait(false);
Console.WriteLine("item returning");
}
public bool Complete(bool success = true)
{
Console.WriteLine("item completing");
// this never returns, see test
_completionSource.SetResult(0);
Console.WriteLine("item returning from completing");
return true;
}
public void Run()
{
throw new NotImplementedException();
}
public bool IsAsync { get { return true; } }
public void Dispose()
{}
}
}
}
@@ -32,6 +32,7 @@ namespace Umbraco.Tests.Scoping
private static void ClearFiles()
{
TestHelper.DeleteDirectory(IOHelper.MapPath("media"));
TestHelper.DeleteDirectory(IOHelper.MapPath("FileSysTests"));
TestHelper.DeleteDirectory(IOHelper.MapPath("App_Data"));
}
@@ -43,6 +44,8 @@ namespace Umbraco.Tests.Scoping
var physMediaFileSystem = new PhysicalFileSystem(IOHelper.MapPath("media"), "ignore");
var mediaFileSystem = FileSystemProviderManager.Current.MediaFileSystem;
Assert.IsFalse(physMediaFileSystem.FileExists("f1.txt"));
var scopeProvider = ApplicationContext.ScopeProvider;
using (var scope = scopeProvider.CreateScope(scopeFileSystems: true))
{
@@ -1785,6 +1785,74 @@ namespace Umbraco.Tests.Services
Assert.IsTrue(content.HasPublishedVersion());
}
[Test]
public void Can_Get_Paged_Children()
{
var service = ServiceContext.ContentService;
// Start by cleaning the "db"
var umbTextPage = service.GetById(new Guid("B58B3AD4-62C2-4E27-B1BE-837BD7C533E0"));
service.Delete(umbTextPage);
var contentType = MockedContentTypes.CreateSimpleContentType();
ServiceContext.ContentTypeService.Save(contentType);
for (int i = 0; i < 10; i++)
{
var c1 = MockedContent.CreateSimpleContent(contentType);
ServiceContext.ContentService.Save(c1);
}
long total;
var entities = service.GetPagedChildren(-1, 0, 6, out total).ToArray();
Assert.That(entities.Length, Is.EqualTo(6));
Assert.That(total, Is.EqualTo(10));
entities = service.GetPagedChildren(-1, 1, 6, out total).ToArray();
Assert.That(entities.Length, Is.EqualTo(4));
Assert.That(total, Is.EqualTo(10));
}
[Test]
public void Can_Get_Paged_Children_Dont_Get_Descendants()
{
var service = ServiceContext.ContentService;
// Start by cleaning the "db"
var umbTextPage = service.GetById(new Guid("B58B3AD4-62C2-4E27-B1BE-837BD7C533E0"));
service.Delete(umbTextPage);
var contentType = MockedContentTypes.CreateSimpleContentType();
ServiceContext.ContentTypeService.Save(contentType);
// only add 9 as we also add a content with children
for (int i = 0; i < 9; i++)
{
var c1 = MockedContent.CreateSimpleContent(contentType);
ServiceContext.ContentService.Save(c1);
}
var willHaveChildren = MockedContent.CreateSimpleContent(contentType);
ServiceContext.ContentService.Save(willHaveChildren);
for (int i = 0; i < 10; i++)
{
var c1 = MockedContent.CreateSimpleContent(contentType, "Content" + i, willHaveChildren.Id);
ServiceContext.ContentService.Save(c1);
}
long total;
// children in root including the folder - not the descendants in the folder
var entities = service.GetPagedChildren(-1, 0, 6, out total).ToArray();
Assert.That(entities.Length, Is.EqualTo(6));
Assert.That(total, Is.EqualTo(10));
entities = service.GetPagedChildren(-1, 1, 6, out total).ToArray();
Assert.That(entities.Length, Is.EqualTo(4));
Assert.That(total, Is.EqualTo(10));
// children in folder
entities = service.GetPagedChildren(willHaveChildren.Id, 0, 6, out total).ToArray();
Assert.That(entities.Length, Is.EqualTo(6));
Assert.That(total, Is.EqualTo(10));
entities = service.GetPagedChildren(willHaveChildren.Id, 1, 6, out total).ToArray();
Assert.That(entities.Length, Is.EqualTo(4));
Assert.That(total, Is.EqualTo(10));
}
private IEnumerable<IContent> CreateContentHierarchy()
{
var contentType = ServiceContext.ContentTypeService.GetContentType("umbTextpage");
@@ -145,6 +145,70 @@ namespace Umbraco.Tests.Services
Assert.That(resolvedMedia.GetValue(Constants.Conventions.Media.File).ToString().Contains(mediaPath));
}
[Test]
public void Can_Get_Paged_Children()
{
var mediaType = MockedContentTypes.CreateImageMediaType("Image2");
ServiceContext.ContentTypeService.Save(mediaType);
for (int i = 0; i < 10; i++)
{
var c1 = MockedMedia.CreateMediaImage(mediaType, -1);
ServiceContext.MediaService.Save(c1);
}
var service = ServiceContext.MediaService;
long total;
var entities = service.GetPagedChildren(-1, 0, 6, out total).ToArray();
Assert.That(entities.Length, Is.EqualTo(6));
Assert.That(total, Is.EqualTo(10));
entities = service.GetPagedChildren(-1, 1, 6, out total).ToArray();
Assert.That(entities.Length, Is.EqualTo(4));
Assert.That(total, Is.EqualTo(10));
}
[Test]
public void Can_Get_Paged_Children_Dont_Get_Descendants()
{
var mediaType = MockedContentTypes.CreateImageMediaType("Image2");
ServiceContext.ContentTypeService.Save(mediaType);
// only add 9 as we also add a folder with children
for (int i = 0; i < 9; i++)
{
var m1 = MockedMedia.CreateMediaImage(mediaType, -1);
ServiceContext.MediaService.Save(m1);
}
var mediaTypeForFolder = MockedContentTypes.CreateImageMediaType("Folder2");
ServiceContext.ContentTypeService.Save(mediaTypeForFolder);
var mediaFolder = MockedMedia.CreateMediaFolder(mediaTypeForFolder, -1);
ServiceContext.MediaService.Save(mediaFolder);
for (int i = 0; i < 10; i++)
{
var m1 = MockedMedia.CreateMediaImage(mediaType, mediaFolder.Id);
ServiceContext.MediaService.Save(m1);
}
var service = ServiceContext.MediaService;
long total;
// children in root including the folder - not the descendants in the folder
var entities = service.GetPagedChildren(-1, 0, 6, out total).ToArray();
Assert.That(entities.Length, Is.EqualTo(6));
Assert.That(total, Is.EqualTo(10));
entities = service.GetPagedChildren(-1, 1, 6, out total).ToArray();
Assert.That(entities.Length, Is.EqualTo(4));
Assert.That(total, Is.EqualTo(10));
// children in folder
entities = service.GetPagedChildren(mediaFolder.Id, 0, 6, out total).ToArray();
Assert.That(entities.Length, Is.EqualTo(6));
Assert.That(total, Is.EqualTo(10));
entities = service.GetPagedChildren(mediaFolder.Id, 1, 6, out total).ToArray();
Assert.That(entities.Length, Is.EqualTo(4));
Assert.That(total, Is.EqualTo(10));
}
private Tuple<IMedia, IMedia, IMedia, IMedia, IMedia> CreateTrashedTestMedia()
{
//Create and Save folder-Media -> 1050
@@ -24,6 +24,7 @@ using Umbraco.Web.PublishedCache.XmlPublishedCache;
using Umbraco.Web.Security;
using umbraco.BusinessLogic;
using Umbraco.Core.Events;
using Umbraco.Core.IO;
using Umbraco.Core.Scoping;
namespace Umbraco.Tests.TestHelpers
@@ -109,6 +110,7 @@ namespace Umbraco.Tests.TestHelpers
{
IsReady = true
};
return _appContext;
}
@@ -18,6 +18,7 @@ using Umbraco.Web;
using Umbraco.Web.Models.Mapping;
using umbraco.BusinessLogic;
using Umbraco.Core.Events;
using Umbraco.Core.IO;
using Umbraco.Core.Scoping;
namespace Umbraco.Tests.TestHelpers
@@ -150,6 +151,11 @@ namespace Umbraco.Tests.TestHelpers
{
var applicationContext = CreateApplicationContext();
ApplicationContext.Current = applicationContext;
// FileSystemProviderManager captures the current ApplicationContext ScopeProvider
// in its current static instance (yea...) so we need to reset it here to ensure
// it is using the proper ScopeProvider
FileSystemProviderManager.Current.Reset();
}
protected virtual ApplicationContext CreateApplicationContext()
@@ -170,6 +176,7 @@ namespace Umbraco.Tests.TestHelpers
{
IsReady = true
};
return applicationContext;
}
+5 -3
View File
@@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Umbraco.Tests</RootNamespace>
<AssemblyName>Umbraco.Tests</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
@@ -92,9 +92,11 @@
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
</Reference>
<Reference Include="Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Semver.2.0.4\lib\net452\Semver.dll</HintPath>
<HintPath>..\packages\Semver.2.0.4\lib\netstandard1.1\Semver.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.configuration" />
<Reference Include="System.Core" />
@@ -169,7 +171,7 @@
<Compile Include="Persistence\PetaPocoExpressionsTests.cs" />
<Compile Include="Persistence\Repositories\LockedRepositoryTests.cs" />
<Compile Include="Persistence\Repositories\RedirectUrlRepositoryTests.cs" />
<Compile Include="Scheduling\DeployTest.cs" />
<Compile Include="Scheduling\BackgroundTaskRunnerTests2.cs" />
<Compile Include="Routing\NiceUrlRoutesTests.cs" />
<Compile Include="Scoping\EventNameExtractorTests.cs" />
<Compile Include="Scoping\LeakTests.cs" />
+5 -1
View File
@@ -21,7 +21,11 @@
<package id="NUnit" version="2.6.2" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<package id="Selenium.WebDriver" version="2.32.0" targetFramework="net45" />
<package id="Semver" version="2.0.4" targetFramework="net462" />
<package id="Semver" version="2.0.4" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
<package id="SqlServerCE" version="4.0.0.1" targetFramework="net45" />
<package id="System.Runtime" version="4.1.0" targetFramework="net45" />
<package id="System.Runtime.Extensions" version="4.1.0" targetFramework="net45" />
<package id="System.Runtime.InteropServices" version="4.1.0" targetFramework="net45" />
<package id="System.Text.RegularExpressions" version="4.1.0" targetFramework="net45" />
</packages>
+1 -1
View File
@@ -25,7 +25,7 @@
"jquery-migrate": "1.4.0",
"angular-dynamic-locale": "0.1.28",
"ng-file-upload": "~7.3.8",
"tinymce": "~4.1.10",
"tinymce": "~4.5.3",
"codemirror": "~5.3.0",
"angular-local-storage": "~0.2.3",
"moment": "~2.10.3",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 367 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Some files were not shown because too many files have changed in this diff Show More