Merge remote-tracking branch 'origin/6.2.0' into 7.0.0

Conflicts:
	.gitignore
	build/Build.bat
	src/Umbraco.Core/Configuration/UmbracoVersion.cs
	src/Umbraco.Core/Models/PropertyExtensions.cs
	src/Umbraco.Core/TypeFinder.cs
	src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
	src/Umbraco.Web.UI/config/ClientDependency.config
	src/Umbraco.Web/Umbraco.Web.csproj
	src/Umbraco.Web/UmbracoContext.cs
This commit is contained in:
Shannon
2013-08-29 15:18:19 +10:00
35 changed files with 1126 additions and 572 deletions
+3
View File
@@ -91,3 +91,6 @@ src/Umbraco.Web.UI/App_Plugins/*
src/*.psess
src/*.vspx
src/Umbraco.Web.UI/umbraco/js/routes.js.*
NDependOut/*
*.ndproj
QueryResult.htm
+19
View File
@@ -187,6 +187,25 @@ namespace Umbraco.Core
return String.Empty;
}
/// <summary>
/// Returns the value of the key value based on the key as it's string value, if the key is not found or is an empty string, then the provided default value is returned
/// </summary>
/// <param name="d"></param>
/// <param name="key"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static string GetValueAsString<TKey, TVal>(this IDictionary<TKey, TVal> d, TKey key, string defaultValue)
{
if (d.ContainsKey(key))
{
var value = d[key].ToString();
if (value != string.Empty)
return value;
}
return defaultValue;
}
/// <summary>contains key ignore case.</summary>
/// <param name="dictionary">The dictionary.</param>
/// <param name="key">The key.</param>
@@ -146,7 +146,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
private void CreateUmbracoUserTypeData()
{
_database.Insert("umbracoUserType", "id", false, new UserTypeDto { Id = 1, Alias = "admin", Name = "Administrators", DefaultPermissions = "CADMOSKTPIURZ:5F" });
_database.Insert("umbracoUserType", "id", false, new UserTypeDto { Id = 1, Alias = "admin", Name = "Administrators", DefaultPermissions = "CADMOSKTPIURZ:5F7" });
_database.Insert("umbracoUserType", "id", false, new UserTypeDto { Id = 2, Alias = "writer", Name = "Writer", DefaultPermissions = "CAH:F" });
_database.Insert("umbracoUserType", "id", false, new UserTypeDto { Id = 3, Alias = "editor", Name = "Editors", DefaultPermissions = "CADMOSKTPUZ:5F" });
_database.Insert("umbracoUserType", "id", false, new UserTypeDto { Id = 4, Alias = "translator", Name = "Translator", DefaultPermissions = "AF" });
+18 -4
View File
@@ -5,6 +5,7 @@ using System.Linq;
using System.Xml.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Dynamics;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Services;
@@ -35,7 +36,7 @@ namespace Umbraco.Core
/// </summary>
internal static Func<string, string, Guid> GetDataTypeCallback = null;
private static readonly ConcurrentDictionary<Tuple<string, string>, Guid> PropertyTypeCache = new ConcurrentDictionary<Tuple<string, string>, Guid>();
private static readonly ConcurrentDictionary<Tuple<string, string, PublishedItemType>, Guid> PropertyTypeCache = new ConcurrentDictionary<Tuple<string, string, PublishedItemType>, Guid>();
/// <summary>
/// Return the GUID Id for the data type assigned to the document type with the property alias
@@ -43,16 +44,29 @@ namespace Umbraco.Core
/// <param name="applicationContext"></param>
/// <param name="docTypeAlias"></param>
/// <param name="propertyAlias"></param>
/// <param name="itemType"></param>
/// <returns></returns>
internal static Guid GetDataType(ApplicationContext applicationContext, string docTypeAlias, string propertyAlias)
internal static Guid GetDataType(ApplicationContext applicationContext, string docTypeAlias, string propertyAlias, PublishedItemType itemType)
{
if (GetDataTypeCallback != null)
return GetDataTypeCallback(docTypeAlias, propertyAlias);
var key = new Tuple<string, string>(docTypeAlias, propertyAlias);
var key = new Tuple<string, string, PublishedItemType>(docTypeAlias, propertyAlias, itemType);
return PropertyTypeCache.GetOrAdd(key, tuple =>
{
var result = applicationContext.Services.ContentTypeService.GetContentType(docTypeAlias);
IContentTypeComposition result = null;
switch (itemType)
{
case PublishedItemType.Content:
result = applicationContext.Services.ContentTypeService.GetContentType(docTypeAlias);
break;
case PublishedItemType.Media:
result = applicationContext.Services.ContentTypeService.GetMediaType(docTypeAlias);
break;
default:
throw new ArgumentOutOfRangeException("itemType");
}
if (result == null) return Guid.Empty;
//SD: we need to check for 'any' here because the collection is backed by KeyValuePair which is a struct
+366 -341
View File
@@ -19,54 +19,56 @@ using Umbraco.Core.IO;
namespace Umbraco.Core
{
/// <summary>
/// A utility class to find all classes of a certain type by reflection in the current bin folder
/// of the web application.
/// </summary>
public static class TypeFinder
{
private static readonly ConcurrentBag<Assembly> LocalFilteredAssemblyCache = new ConcurrentBag<Assembly>();
private static readonly ReaderWriterLockSlim LocalFilteredAssemblyCacheLocker = new ReaderWriterLockSlim();
private static ReadOnlyCollection<Assembly> _allAssemblies = null;
private static ReadOnlyCollection<Assembly> _binFolderAssemblies = null;
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
/// <summary>
/// A utility class to find all classes of a certain type by reflection in the current bin folder
/// of the web application.
/// </summary>
public static class TypeFinder
{
private static readonly HashSet<Assembly> LocalFilteredAssemblyCache = new HashSet<Assembly>();
private static readonly ReaderWriterLockSlim LocalFilteredAssemblyCacheLocker = new ReaderWriterLockSlim();
private static HashSet<Assembly> _allAssemblies = null;
private static HashSet<Assembly> _binFolderAssemblies = null;
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
/// <summary>
/// lazily load a reference to all assemblies and only local assemblies.
/// This is a modified version of: http://www.dominicpettifer.co.uk/Blog/44/how-to-get-a-reference-to-all-assemblies-in-the--bin-folder
/// </summary>
/// <remarks>
/// We do this because we cannot use AppDomain.Current.GetAssemblies() as this will return only assemblies that have been
/// loaded in the CLR, not all assemblies.
/// See these threads:
/// http://issues.umbraco.org/issue/U5-198
/// http://stackoverflow.com/questions/3552223/asp-net-appdomain-currentdomain-getassemblies-assemblies-missing-after-app
/// http://stackoverflow.com/questions/2477787/difference-between-appdomain-getassemblies-and-buildmanager-getreferencedassembl
/// </remarks>
internal static IEnumerable<Assembly> GetAllAssemblies()
{
if (_allAssemblies == null)
{
using (new WriteLock(Locker))
{
List<Assembly> assemblies = null;
try
{
var isHosted = HttpContext.Current != null;
/// <summary>
/// lazily load a reference to all assemblies and only local assemblies.
/// This is a modified version of: http://www.dominicpettifer.co.uk/Blog/44/how-to-get-a-reference-to-all-assemblies-in-the--bin-folder
/// </summary>
/// <remarks>
/// We do this because we cannot use AppDomain.Current.GetAssemblies() as this will return only assemblies that have been
/// loaded in the CLR, not all assemblies.
/// See these threads:
/// http://issues.umbraco.org/issue/U5-198
/// http://stackoverflow.com/questions/3552223/asp-net-appdomain-currentdomain-getassemblies-assemblies-missing-after-app
/// http://stackoverflow.com/questions/2477787/difference-between-appdomain-getassemblies-and-buildmanager-getreferencedassembl
/// </remarks>
internal static HashSet<Assembly> GetAllAssemblies()
{
using (var lck = new UpgradeableReadLock(Locker))
{
if (_allAssemblies == null)
{
try
{
if (isHosted)
{
assemblies = new List<Assembly>(BuildManager.GetReferencedAssemblies().Cast<Assembly>());
}
}
catch (InvalidOperationException e)
{
if (!(e.InnerException is SecurityException))
throw;
}
lck.UpgradeToWriteLock();
HashSet<Assembly> assemblies = null;
try
{
var isHosted = HttpContext.Current != null;
try
{
if (isHosted)
{
assemblies = new HashSet<Assembly>(BuildManager.GetReferencedAssemblies().Cast<Assembly>());
}
}
catch (InvalidOperationException e)
{
if (!(e.InnerException is SecurityException))
throw;
}
if (assemblies == null)
@@ -77,7 +79,7 @@ namespace Umbraco.Core
var binAssemblyFiles = Directory.GetFiles(binFolder, "*.dll", SearchOption.TopDirectoryOnly).ToList();
//var binFolder = Assembly.GetExecutingAssembly().GetAssemblyFile().Directory;
//var binAssemblyFiles = Directory.GetFiles(binFolder.FullName, "*.dll", SearchOption.TopDirectoryOnly).ToList();
assemblies = new List<Assembly>();
assemblies = new HashSet<Assembly>();
foreach (var a in binAssemblyFiles)
{
try
@@ -99,151 +101,161 @@ namespace Umbraco.Core
}
}
}
//if for some reason they are still no assemblies, then use the AppDomain to load in already loaded assemblies.
if (!assemblies.Any())
{
assemblies.AddRange(AppDomain.CurrentDomain.GetAssemblies().ToList());
}
if (!assemblies.Any())
{
foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
{
assemblies.Add(a);
}
}
//here we are trying to get the App_Code assembly
var fileExtensions = new[] {".cs", ".vb"}; //only vb and cs files are supported
var appCodeFolder = new DirectoryInfo(IOHelper.MapPath(IOHelper.ResolveUrl("~/App_code")));
//check if the folder exists and if there are any files in it with the supported file extensions
if (appCodeFolder.Exists && (fileExtensions.Any(x => appCodeFolder.GetFiles("*" + x).Any())))
{
var appCodeAssembly = Assembly.Load("App_Code");
if (!assemblies.Contains(appCodeAssembly)) // BuildManager will find App_Code already
assemblies.Add(appCodeAssembly);
}
//here we are trying to get the App_Code assembly
var fileExtensions = new[] { ".cs", ".vb" }; //only vb and cs files are supported
var appCodeFolder = new DirectoryInfo(IOHelper.MapPath(IOHelper.ResolveUrl("~/App_code")));
//check if the folder exists and if there are any files in it with the supported file extensions
if (appCodeFolder.Exists && (fileExtensions.Any(x => appCodeFolder.GetFiles("*" + x).Any())))
{
var appCodeAssembly = Assembly.Load("App_Code");
if (!assemblies.Contains(appCodeAssembly)) // BuildManager will find App_Code already
assemblies.Add(appCodeAssembly);
}
//now set the _allAssemblies
_allAssemblies = new ReadOnlyCollection<Assembly>(assemblies);
//now set the _allAssemblies
_allAssemblies = new HashSet<Assembly>(assemblies);
}
catch (InvalidOperationException e)
{
if (!(e.InnerException is SecurityException))
throw;
}
catch (InvalidOperationException e)
{
if (!(e.InnerException is SecurityException))
throw;
_binFolderAssemblies = _allAssemblies;
}
}
}
_binFolderAssemblies = _allAssemblies;
}
}
return _allAssemblies;
}
/// <summary>
/// Returns only assemblies found in the bin folder that have been loaded into the app domain.
/// </summary>
/// <returns></returns>
/// <remarks>
/// This will be used if we implement App_Plugins from Umbraco v5 but currently it is not used.
/// </remarks>
internal static IEnumerable<Assembly> GetBinAssemblies()
{
return _allAssemblies;
}
}
if (_binFolderAssemblies == null)
{
using (new WriteLock(Locker))
{
var assemblies = GetAssembliesWithKnownExclusions().ToArray();
var binFolder = Assembly.GetExecutingAssembly().GetAssemblyFile().Directory;
var binAssemblyFiles = Directory.GetFiles(binFolder.FullName, "*.dll", SearchOption.TopDirectoryOnly).ToList();
var domainAssemblyNames = binAssemblyFiles.Select(AssemblyName.GetAssemblyName);
var safeDomainAssemblies = new List<Assembly>();
var binFolderAssemblies = new List<Assembly>();
/// <summary>
/// Returns only assemblies found in the bin folder that have been loaded into the app domain.
/// </summary>
/// <returns></returns>
/// <remarks>
/// This will be used if we implement App_Plugins from Umbraco v5 but currently it is not used.
/// </remarks>
internal static HashSet<Assembly> GetBinAssemblies()
{
foreach (var a in assemblies)
{
try
{
//do a test to see if its queryable in med trust
var assemblyFile = a.GetAssemblyFile();
safeDomainAssemblies.Add(a);
}
catch (SecurityException)
{
//we will just ignore this because this will fail
//in medium trust for system assemblies, we get an exception but we just want to continue until we get to
//an assembly that is ok.
}
}
if (_binFolderAssemblies == null)
{
using (new WriteLock(Locker))
{
var assemblies = GetAssembliesWithKnownExclusions().ToArray();
var binFolder = Assembly.GetExecutingAssembly().GetAssemblyFile().Directory;
var binAssemblyFiles = Directory.GetFiles(binFolder.FullName, "*.dll", SearchOption.TopDirectoryOnly).ToList();
var domainAssemblyNames = binAssemblyFiles.Select(AssemblyName.GetAssemblyName);
var safeDomainAssemblies = new HashSet<Assembly>();
var binFolderAssemblies = new HashSet<Assembly>();
foreach (var assemblyName in domainAssemblyNames)
{
try
{
var foundAssembly =
safeDomainAssemblies.FirstOrDefault(a => a.GetAssemblyFile() == assemblyName.GetAssemblyFile());
if (foundAssembly != null)
{
binFolderAssemblies.Add(foundAssembly);
}
}
catch (SecurityException)
{
//we will just ignore this because if we are trying to do a call to:
// AssemblyName.ReferenceMatchesDefinition(a.GetName(), assemblyName)))
//in medium trust for system assemblies, we get an exception but we just want to continue until we get to
//an assembly that is ok.
}
}
foreach (var a in assemblies)
{
try
{
//do a test to see if its queryable in med trust
var assemblyFile = a.GetAssemblyFile();
safeDomainAssemblies.Add(a);
}
catch (SecurityException)
{
//we will just ignore this because this will fail
//in medium trust for system assemblies, we get an exception but we just want to continue until we get to
//an assembly that is ok.
}
}
_binFolderAssemblies = new ReadOnlyCollection<Assembly>(binFolderAssemblies);
}
}
return _binFolderAssemblies;
}
foreach (var assemblyName in domainAssemblyNames)
{
try
{
var foundAssembly =
safeDomainAssemblies.FirstOrDefault(a => a.GetAssemblyFile() == assemblyName.GetAssemblyFile());
if (foundAssembly != null)
{
binFolderAssemblies.Add(foundAssembly);
}
}
catch (SecurityException)
{
//we will just ignore this because if we are trying to do a call to:
// AssemblyName.ReferenceMatchesDefinition(a.GetName(), assemblyName)))
//in medium trust for system assemblies, we get an exception but we just want to continue until we get to
//an assembly that is ok.
}
}
/// <summary>
/// Return a list of found local Assemblies excluding the known assemblies we don't want to scan
/// and exluding the ones passed in and excluding the exclusion list filter, the results of this are
/// cached for perforance reasons.
/// </summary>
/// <param name="excludeFromResults"></param>
/// <returns></returns>
internal static IEnumerable<Assembly> GetAssembliesWithKnownExclusions(
IEnumerable<Assembly> excludeFromResults = null)
{
if (LocalFilteredAssemblyCache.Any()) return LocalFilteredAssemblyCache;
using (new WriteLock(LocalFilteredAssemblyCacheLocker))
{
var assemblies = GetFilteredAssemblies(excludeFromResults, KnownAssemblyExclusionFilter);
assemblies.ForEach(LocalFilteredAssemblyCache.Add);
}
return LocalFilteredAssemblyCache;
}
_binFolderAssemblies = new HashSet<Assembly>(binFolderAssemblies);
}
}
return _binFolderAssemblies;
}
/// <summary>
/// Return a list of found local Assemblies and exluding the ones passed in and excluding the exclusion list filter
/// </summary>
/// <param name="excludeFromResults"></param>
/// <param name="exclusionFilter"></param>
/// <returns></returns>
private static IEnumerable<Assembly> GetFilteredAssemblies(
IEnumerable<Assembly> excludeFromResults = null,
string[] exclusionFilter = null)
{
if (excludeFromResults == null)
excludeFromResults = new List<Assembly>();
if (exclusionFilter == null)
exclusionFilter = new string[] { };
/// <summary>
/// Return a list of found local Assemblies excluding the known assemblies we don't want to scan
/// and exluding the ones passed in and excluding the exclusion list filter, the results of this are
/// cached for perforance reasons.
/// </summary>
/// <param name="excludeFromResults"></param>
/// <returns></returns>
internal static HashSet<Assembly> GetAssembliesWithKnownExclusions(
IEnumerable<Assembly> excludeFromResults = null)
{
using (var lck = new UpgradeableReadLock(LocalFilteredAssemblyCacheLocker))
{
if (LocalFilteredAssemblyCache.Any()) return LocalFilteredAssemblyCache;
return GetAllAssemblies()
.Where(x => !excludeFromResults.Contains(x)
&& !x.GlobalAssemblyCache
&& !exclusionFilter.Any(f => x.FullName.StartsWith(f)));
}
lck.UpgradeToWriteLock();
/// <summary>
/// this is our assembly filter to filter out known types that def dont contain types we'd like to find or plugins
/// </summary>
/// <remarks>
/// NOTE the comma vs period... comma delimits the name in an Assembly FullName property so if it ends with comma then its an exact name match
/// </remarks>
internal static readonly string[] KnownAssemblyExclusionFilter = new[]
var assemblies = GetFilteredAssemblies(excludeFromResults, KnownAssemblyExclusionFilter);
foreach (var a in assemblies)
{
LocalFilteredAssemblyCache.Add(a);
}
return LocalFilteredAssemblyCache;
}
}
/// <summary>
/// Return a distinct list of found local Assemblies and exluding the ones passed in and excluding the exclusion list filter
/// </summary>
/// <param name="excludeFromResults"></param>
/// <param name="exclusionFilter"></param>
/// <returns></returns>
private static IEnumerable<Assembly> GetFilteredAssemblies(
IEnumerable<Assembly> excludeFromResults = null,
string[] exclusionFilter = null)
{
if (excludeFromResults == null)
excludeFromResults = new HashSet<Assembly>();
if (exclusionFilter == null)
exclusionFilter = new string[] { };
return GetAllAssemblies()
.Where(x => !excludeFromResults.Contains(x)
&& !x.GlobalAssemblyCache
&& !exclusionFilter.Any(f => x.FullName.StartsWith(f)));
}
/// <summary>
/// this is our assembly filter to filter out known types that def dont contain types we'd like to find or plugins
/// </summary>
/// <remarks>
/// NOTE the comma vs period... comma delimits the name in an Assembly FullName property so if it ends with comma then its an exact name match
/// </remarks>
internal static readonly string[] KnownAssemblyExclusionFilter = new[]
{
"mscorlib,",
"System.",
@@ -287,11 +299,11 @@ namespace Umbraco.Core
/// <typeparam name="T"></typeparam>
/// <typeparam name="TAttribute"></typeparam>
/// <returns></returns>
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>()
where TAttribute : Attribute
{
return FindClassesOfTypeWithAttribute<T, TAttribute>(GetAssembliesWithKnownExclusions(), true);
}
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>()
where TAttribute : Attribute
{
return FindClassesOfTypeWithAttribute<T, TAttribute>(GetAssembliesWithKnownExclusions(), true);
}
/// <summary>
/// Finds any classes derived from the type T that contain the attribute TAttribute
@@ -300,11 +312,11 @@ namespace Umbraco.Core
/// <typeparam name="TAttribute"></typeparam>
/// <param name="assemblies"></param>
/// <returns></returns>
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(IEnumerable<Assembly> assemblies)
where TAttribute : Attribute
{
return FindClassesOfTypeWithAttribute<T, TAttribute>(assemblies, true);
}
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(IEnumerable<Assembly> assemblies)
where TAttribute : Attribute
{
return FindClassesOfTypeWithAttribute<T, TAttribute>(assemblies, true);
}
/// <summary>
/// Finds any classes derived from the type T that contain the attribute TAttribute
@@ -314,13 +326,13 @@ namespace Umbraco.Core
/// <param name="assemblies"></param>
/// <param name="onlyConcreteClasses"></param>
/// <returns></returns>
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(
IEnumerable<Assembly> assemblies,
bool onlyConcreteClasses)
where TAttribute : Attribute
{
return FindClassesOfTypeWithAttribute<TAttribute>(typeof (T), assemblies, onlyConcreteClasses);
}
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(
IEnumerable<Assembly> assemblies,
bool onlyConcreteClasses)
where TAttribute : Attribute
{
return FindClassesOfTypeWithAttribute<TAttribute>(typeof(T), assemblies, onlyConcreteClasses);
}
/// <summary>
/// Finds any classes derived from the assignTypeFrom Type that contain the attribute TAttribute
@@ -330,85 +342,85 @@ namespace Umbraco.Core
/// <param name="assemblies"></param>
/// <param name="onlyConcreteClasses"></param>
/// <returns></returns>
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<TAttribute>(
Type assignTypeFrom,
IEnumerable<Assembly> assemblies,
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<TAttribute>(
Type assignTypeFrom,
IEnumerable<Assembly> assemblies,
bool onlyConcreteClasses)
where TAttribute : Attribute
{
if (assemblies == null) throw new ArgumentNullException("assemblies");
return GetClasses(assignTypeFrom, assemblies, onlyConcreteClasses,
{
if (assemblies == null) throw new ArgumentNullException("assemblies");
return GetClasses(assignTypeFrom, assemblies, onlyConcreteClasses,
//the additional filter will ensure that any found types also have the attribute applied.
t => t.GetCustomAttributes<TAttribute>(false).Any());
}
t => t.GetCustomAttributes<TAttribute>(false).Any());
}
/// <summary>
/// Searches all filtered local assemblies specified for classes of the type passed in.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IEnumerable<Type> FindClassesOfType<T>()
{
return FindClassesOfType<T>(GetAssembliesWithKnownExclusions(), true);
}
/// <summary>
/// Searches all filtered local assemblies specified for classes of the type passed in.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IEnumerable<Type> FindClassesOfType<T>()
{
return FindClassesOfType<T>(GetAssembliesWithKnownExclusions(), true);
}
/// <summary>
/// Returns all types found of in the assemblies specified of type T
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="assemblies"></param>
/// <param name="onlyConcreteClasses"></param>
/// <returns></returns>
public static IEnumerable<Type> FindClassesOfType<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
{
if (assemblies == null) throw new ArgumentNullException("assemblies");
/// <summary>
/// Returns all types found of in the assemblies specified of type T
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="assemblies"></param>
/// <param name="onlyConcreteClasses"></param>
/// <returns></returns>
public static IEnumerable<Type> FindClassesOfType<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
{
if (assemblies == null) throw new ArgumentNullException("assemblies");
return GetClasses(typeof(T), assemblies, onlyConcreteClasses);
}
}
/// <summary>
/// Returns all types found of in the assemblies specified of type T
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="assemblies"></param>
/// <returns></returns>
public static IEnumerable<Type> FindClassesOfType<T>(IEnumerable<Assembly> assemblies)
{
return FindClassesOfType<T>(assemblies, true);
}
/// <summary>
/// Returns all types found of in the assemblies specified of type T
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="assemblies"></param>
/// <returns></returns>
public static IEnumerable<Type> FindClassesOfType<T>(IEnumerable<Assembly> assemblies)
{
return FindClassesOfType<T>(assemblies, true);
}
/// <summary>
/// Finds the classes with attribute.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="assemblies">The assemblies.</param>
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
/// <returns></returns>
public static IEnumerable<Type> FindClassesWithAttribute<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
where T : Attribute
{
return FindClassesWithAttribute(typeof(T), assemblies, onlyConcreteClasses);
}
/// <summary>
/// Finds the classes with attribute.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="assemblies">The assemblies.</param>
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
/// <returns></returns>
public static IEnumerable<Type> FindClassesWithAttribute<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
where T : Attribute
{
return FindClassesWithAttribute(typeof(T), assemblies, onlyConcreteClasses);
}
/// <summary>
/// Finds any classes with the attribute.
/// </summary>
/// <param name="attributeType">The attribute type </param>
/// <param name="assemblies">The assemblies.</param>
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
/// <returns></returns>
public static IEnumerable<Type> FindClassesWithAttribute(
Type attributeType,
IEnumerable<Assembly> assemblies,
bool onlyConcreteClasses)
{
if (assemblies == null) throw new ArgumentNullException("assemblies");
/// <summary>
/// Finds any classes with the attribute.
/// </summary>
/// <param name="attributeType">The attribute type </param>
/// <param name="assemblies">The assemblies.</param>
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
/// <returns></returns>
public static IEnumerable<Type> FindClassesWithAttribute(
Type attributeType,
IEnumerable<Assembly> assemblies,
bool onlyConcreteClasses)
{
if (assemblies == null) throw new ArgumentNullException("assemblies");
if (TypeHelper.IsTypeAssignableFrom<Attribute>(attributeType) == false)
throw new ArgumentException("The type specified: " + attributeType + " is not an Attribute type");
if (TypeHelper.IsTypeAssignableFrom<Attribute>(attributeType) == false)
throw new ArgumentException("The type specified: " + attributeType + " is not an Attribute type");
var foundAssignableTypes = new List<Type>();
var foundAssignableTypes = new HashSet<Type>();
var assemblyList = assemblies.ToArray();
@@ -418,71 +430,74 @@ namespace Umbraco.Core
var referencedAssemblies = TypeHelper.GetReferencedAssemblies(attributeType, assemblyList);
foreach (var a in referencedAssemblies)
{
{
//get all types in the assembly that are sub types of the current type
var allTypes = GetTypesWithFormattedException(a).ToArray();
var types = allTypes.Where(t => TypeHelper.IsNonStaticClass(t)
&& (onlyConcreteClasses == false || t.IsAbstract == false)
//the type must have this attribute
var types = allTypes.Where(t => TypeHelper.IsNonStaticClass(t)
&& (onlyConcreteClasses == false || t.IsAbstract == false)
//the type must have this attribute
&& t.GetCustomAttributes(attributeType, false).Any());
foundAssignableTypes.AddRange(types);
}
foreach (var t in types)
{
foundAssignableTypes.Add(t);
}
}
return foundAssignableTypes;
}
return foundAssignableTypes;
}
/// <summary>
/// Finds the classes with attribute.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="assemblies">The assemblies.</param>
/// <returns></returns>
public static IEnumerable<Type> FindClassesWithAttribute<T>(IEnumerable<Assembly> assemblies)
where T : Attribute
{
return FindClassesWithAttribute<T>(assemblies, true);
}
/// <summary>
/// Finds the classes with attribute.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="assemblies">The assemblies.</param>
/// <returns></returns>
public static IEnumerable<Type> FindClassesWithAttribute<T>(IEnumerable<Assembly> assemblies)
where T : Attribute
{
return FindClassesWithAttribute<T>(assemblies, true);
}
/// <summary>
/// Finds the classes with attribute in filtered local assemblies
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IEnumerable<Type> FindClassesWithAttribute<T>()
where T : Attribute
{
return FindClassesWithAttribute<T>(GetAssembliesWithKnownExclusions());
}
/// <summary>
/// Finds the classes with attribute in filtered local assemblies
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IEnumerable<Type> FindClassesWithAttribute<T>()
where T : Attribute
{
return FindClassesWithAttribute<T>(GetAssembliesWithKnownExclusions());
}
#region Private methods
/// <summary>
/// Finds types that are assignable from the assignTypeFrom parameter and will scan for these types in the assembly
/// list passed in, however we will only scan assemblies that have a reference to the assignTypeFrom Type or any type
/// deriving from the base type.
/// </summary>
/// <param name="assignTypeFrom"></param>
/// <param name="assemblies"></param>
/// <param name="onlyConcreteClasses"></param>
/// <param name="additionalFilter">An additional filter to apply for what types will actually be included in the return value</param>
/// <returns></returns>
private static IEnumerable<Type> GetClasses(
Type assignTypeFrom,
IEnumerable<Assembly> assemblies,
#region Private methods
/// <summary>
/// Finds types that are assignable from the assignTypeFrom parameter and will scan for these types in the assembly
/// list passed in, however we will only scan assemblies that have a reference to the assignTypeFrom Type or any type
/// deriving from the base type.
/// </summary>
/// <param name="assignTypeFrom"></param>
/// <param name="assemblies"></param>
/// <param name="onlyConcreteClasses"></param>
/// <param name="additionalFilter">An additional filter to apply for what types will actually be included in the return value</param>
/// <returns></returns>
private static IEnumerable<Type> GetClasses(
Type assignTypeFrom,
IEnumerable<Assembly> assemblies,
bool onlyConcreteClasses,
Func<Type, bool> additionalFilter = null)
{
{
//the default filter will always return true.
if (additionalFilter == null)
{
additionalFilter = type => true;
}
var foundAssignableTypes = new List<Type>();
var foundAssignableTypes = new HashSet<Type>();
var assemblyList = assemblies.ToArray();
@@ -510,8 +525,11 @@ namespace Umbraco.Core
.ToArray();
//add the types to our list to return
foundAssignableTypes.AddRange(filteredTypes);
foreach (var t in filteredTypes)
{
foundAssignableTypes.Add(t);
}
//now we need to include types that may be inheriting from sub classes of the type being searched for
//so we will search in assemblies that reference those types too.
foreach (var subTypesInAssembly in allSubTypes.GroupBy(x => x.Assembly))
@@ -529,55 +547,62 @@ namespace Umbraco.Core
//if there's a base class amongst the types then we'll only search for that type.
//otherwise we'll have to search for all of them.
var subTypesToSearch = new List<Type>();
var subTypesToSearch = new HashSet<Type>();
if (baseClassAttempt.Success)
{
subTypesToSearch.Add(baseClassAttempt.Result);
}
else
{
subTypesToSearch.AddRange(subTypeList);
foreach (var t in subTypeList)
{
subTypesToSearch.Add(t);
}
}
foreach (var typeToSearch in subTypesToSearch)
{
//recursively find the types inheriting from this sub type in the other non-scanned assemblies.
var foundTypes = GetClasses(typeToSearch, otherAssemblies, onlyConcreteClasses, additionalFilter);
foundAssignableTypes.AddRange(foundTypes);
foreach (var f in foundTypes)
{
foundAssignableTypes.Add(f);
}
}
}
}
return foundAssignableTypes;
}
}
return foundAssignableTypes;
}
private static IEnumerable<Type> GetTypesWithFormattedException(Assembly a)
{
//if the assembly is dynamic, do not try to scan it
if (a.IsDynamic)
return Enumerable.Empty<Type>();
private static IEnumerable<Type> GetTypesWithFormattedException(Assembly a)
{
//if the assembly is dynamic, do not try to scan it
if (a.IsDynamic)
return Enumerable.Empty<Type>();
try
{
try
{
//return a.GetExportedTypes();
return a.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
var sb = new StringBuilder();
sb.AppendLine("Could not load types from assembly " + a.FullName + ", errors:");
foreach (var loaderException in ex.LoaderExceptions.WhereNotNull())
{
sb.AppendLine("Exception: " + loaderException);
}
throw new ReflectionTypeLoadException(ex.Types, ex.LoaderExceptions, sb.ToString());
}
}
}
catch (ReflectionTypeLoadException ex)
{
var sb = new StringBuilder();
sb.AppendLine("Could not load types from assembly " + a.FullName + ", errors:");
foreach (var loaderException in ex.LoaderExceptions.WhereNotNull())
{
sb.AppendLine("Exception: " + loaderException);
}
throw new ReflectionTypeLoadException(ex.Types, ex.LoaderExceptions, sb.ToString());
}
}
#endregion
#endregion
}
}
}
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;
using System.Xml.Linq;
using System.Xml.XPath;
using Examine;
@@ -16,6 +17,7 @@ using Umbraco.Core.Configuration;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
using Umbraco.Tests.UmbracoExamine;
using Umbraco.Web;
using Umbraco.Web.PublishedCache;
@@ -68,6 +70,38 @@ namespace Umbraco.Tests.PublishedContent
return GetNode(id, GetUmbracoContext("/test", 1234));
}
[Test]
public void Get_Property_Value_Uses_Converter()
{
var mType = MockedContentTypes.CreateImageMediaType();
//lets add an RTE to this
mType.PropertyGroups.First().PropertyTypes.Add(
new PropertyType(new Guid(), DataTypeDatabaseType.Nvarchar)
{
Alias = "content",
Name = "Rich Text",
DataTypeDefinitionId = -87 //tiny mce
});
ServiceContext.ContentTypeService.Save(mType);
var media = MockedMedia.CreateMediaImage(mType, -1);
media.Properties["content"].Value = "<div>This is some content</div>";
ServiceContext.MediaService.Save(media);
var publishedMedia = GetNode(media.Id);
var propVal = publishedMedia.GetPropertyValue("content");
Assert.IsTrue(TypeHelper.IsTypeAssignableFrom<IHtmlString>(propVal.GetType()));
Assert.AreEqual("<div>This is some content</div>", propVal.ToString());
var propVal2 = publishedMedia.GetPropertyValue<IHtmlString>("content");
Assert.IsTrue(TypeHelper.IsTypeAssignableFrom<IHtmlString>(propVal2.GetType()));
Assert.AreEqual("<div>This is some content</div>", propVal2.ToString());
var propVal3 = publishedMedia.GetPropertyValue("Content");
Assert.IsTrue(TypeHelper.IsTypeAssignableFrom<IHtmlString>(propVal3.GetType()));
Assert.AreEqual("<div>This is some content</div>", propVal3.ToString());
}
[Test]
public void Ensure_Children_Sorted_With_Examine()
{
@@ -339,7 +373,6 @@ namespace Umbraco.Tests.PublishedContent
Assert.AreEqual(mChild1.Id, publishedSubChild1.Parent.Id);
}
[Test]
public void Ancestors_Without_Examine()
{
+2
View File
@@ -2163,6 +2163,8 @@
<Content Include="Umbraco\PartialViews\Templates\Login.cshtml" />
<Content Include="Umbraco\PartialViews\Templates\EmptyTemplate.cshtml" />
<Content Include="Umbraco\PartialViews\Templates\RegisterMember.cshtml" />
<Content Include="Umbraco\PartialViews\Templates\LoginStatus.cshtml" />
<Content Include="Umbraco\PartialViews\Templates\EditProfile.cshtml" />
<None Include="Umbraco_client\CodeMirror\js\mode\coffeescript\LICENSE" />
<None Include="Umbraco_client\CodeMirror\js\mode\pascal\LICENSE" />
<None Include="Umbraco_client\CodeMirror\js\mode\perl\LICENSE" />
@@ -0,0 +1,52 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage
@using System.Web.Mvc.Html
@using ClientDependency.Core.Mvc
@using umbraco.cms.businesslogic.member
@using Umbraco.Web
@using Umbraco.Web.Models
@using Umbraco.Web.Controllers
@{
var profileModel = new ProfileModel();
Html.EnableClientValidation();
Html.EnableUnobtrusiveJavaScript();
Html.RequiresJs("/umbraco_client/ui/jquery.js");
Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.min.js");
Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.unobtrusive.min.js");
}
@if (Member.IsLoggedOn())
{
@Html.RenderJsHere()
using (Html.BeginUmbracoForm<ProfileController>("HandleUpdateProfile"))
{
<fieldset>
<legend>Edit profile</legend>
@Html.LabelFor(m => profileModel.Name)
@Html.TextBoxFor(m => profileModel.Name)
@Html.ValidationMessageFor(m => profileModel.Name)
<br />
@Html.LabelFor(m => profileModel.Email)
@Html.TextBoxFor(m => profileModel.Email)
@Html.ValidationMessageFor(m => profileModel.Email)
<br />
@for (var i = 0; i < profileModel.MemberProperties.Count; i++)
{
@Html.LabelFor(m => profileModel.MemberProperties[i].Value, profileModel.MemberProperties[i].Name)
@Html.EditorFor(m => profileModel.MemberProperties[i].Value)
@Html.HiddenFor(m => profileModel.MemberProperties[i].Alias)
<br />
}
@Html.HiddenFor(m => profileModel.MemberTypeAlias)
<button>Save</button>
</fieldset>
}
}
@@ -1 +1 @@
@using Umbraco.Web.Macros.PartialViewMacroPage
@inherits Umbraco.Web.Macros.PartialViewMacroPage
@@ -2,24 +2,21 @@
@using System.Web.Mvc.Html
@using ClientDependency.Core.Mvc
@using Umbraco.Web.UmbracoModels
@using Umbraco.Web.UmbracoControllers
@using Umbraco.Web
@using Umbraco.Web.Models
@using Umbraco.Web.Controllers
@{
var loginModel = new LoginModel();
Html.EnableClientValidation();
Html.EnableUnobtrusiveJavaScript();
// TODO: CDF doesn't work at the moment, Shannon is looking at it
//Html.RequiresJs("/umbraco_client/ui/jquery.js");
//Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.min.js");
//Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.unobtrusive.min.js");
var loginModel = new LoginModel();
Html.RequiresJs("/umbraco_client/ui/jquery.js");
Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.min.js");
Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.unobtrusive.min.js");
}
<script src="@Url.Content("~/umbraco_client/ui/jquery.js")" type="text/javascript"></script>
<script src="@Url.Content("~/umbraco_client/Application/JQuery/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/umbraco_client/Application/JQuery/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@Html.RenderJsHere()
@using (Html.BeginUmbracoForm<LoginController>("HandleLogin"))
{
@@ -0,0 +1,30 @@
@inherits Umbraco.Web.Macros.PartialViewMacroPage
@using ClientDependency.Core.Mvc
@using Umbraco.Web
@using Umbraco.Web.Models
@using Umbraco.Web.Controllers
@{
var loginStatusModel = new LoginStatusModel();
Html.EnableClientValidation();
Html.EnableUnobtrusiveJavaScript();
Html.RequiresJs("/umbraco_client/ui/jquery.js");
Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.min.js");
Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.unobtrusive.min.js");
}
@Html.RenderJsHere()
@if (loginStatusModel.IsLoggedIn)
{
<p>You are currently logged in as @loginStatusModel.Name</p>
using (Html.BeginUmbracoForm<LoginStatusController>("HandleLogout"))
{
<fieldset>
<legend>Logout</legend>
<button>Logout</button>
</fieldset>
}
}
@@ -2,53 +2,32 @@
@using System.Web.Mvc.Html
@using ClientDependency.Core.Mvc
@using umbraco.cms.businesslogic.member
@using Umbraco.Web.UmbracoModels
@using Umbraco.Web.UmbracoControllers
@using Umbraco.Web
@using Umbraco.Web.Models
@using Umbraco.Web.Controllers
@{
var registerModel = new RegisterModel();
Html.EnableClientValidation();
Html.EnableUnobtrusiveJavaScript();
// TODO: CDF doesn't work at the moment, Shannon is looking at it
//Html.RequiresJs("/umbraco_client/ui/jquery.js");
//Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.min.js");
//Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.unobtrusive.min.js");
// TODO: Make a helper for this
var memberTypeAlias = "UmbracoMember";
if (Model.MacroParameters.Any() && Model.MacroParameters.ContainsKey("memberTypeAlias"))
{
var alias = Model.MacroParameters["memberTypeAlias"];
if (string.IsNullOrWhiteSpace(alias.ToString()) == false)
{
memberTypeAlias = alias.ToString();
}
}
var registerModel = new RegisterModel
{
MemberProperties = new List<UmbracoProperty>(),
MemberTypeAlias = memberTypeAlias
};
// TODO: Fill model somewhere else
var memberType = MemberType.GetByAlias(registerModel.MemberTypeAlias);
foreach (var prop in memberType.PropertyTypes.Where(memberType.MemberCanEdit))
{
registerModel.MemberProperties.Add(new UmbracoProperty {Alias = prop.Alias, Name = prop.Name, Value = string.Empty});
}
Html.RequiresJs("/umbraco_client/ui/jquery.js");
Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.min.js");
Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.unobtrusive.min.js");
}
<script src="@Url.Content("~/umbraco_client/ui/jquery.js")" type="text/javascript"></script>
<script src="@Url.Content("~/umbraco_client/Application/JQuery/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/umbraco_client/Application/JQuery/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@Html.RenderJsHere()
@using (Html.BeginUmbracoForm<RegisterController>("HandleRegisterMember"))
{
<fieldset>
<legend>Register Member</legend>
@Html.LabelFor(m => registerModel.Name)
@Html.TextBoxFor(m => registerModel.Name)
@Html.ValidationMessageFor(m => registerModel.Name)
<br />
@Html.LabelFor(m => registerModel.Email)
@Html.TextBoxFor(m => registerModel.Email)
@Html.ValidationMessageFor(m => registerModel.Email)
@@ -59,14 +38,16 @@
@Html.ValidationMessageFor(m => registerModel.Password)
<br />
@for (var i = 0; i < registerModel.MemberProperties.Count; i++)
{
@Html.LabelFor(m => registerModel.MemberProperties[i].Value, registerModel.MemberProperties[i].Name)
@Html.EditorFor(m => registerModel.MemberProperties[i].Value)
@Html.HiddenFor(m => registerModel.MemberProperties[i].Alias)
<br />
@if (registerModel.MemberProperties != null) {
for (var i = 0; i < registerModel.MemberProperties.Count; i++)
{
@Html.LabelFor(m => registerModel.MemberProperties[i].Value, registerModel.MemberProperties[i].Name)
@Html.EditorFor(m => registerModel.MemberProperties[i].Value)
@Html.HiddenFor(m => registerModel.MemberProperties[i].Alias)
<br />
}
}
@Html.HiddenFor(m => registerModel.MemberTypeAlias)
<button>Register</button>
@@ -3,5 +3,5 @@
<notFound assembly="umbraco" type="SearchForAlias" />
<notFound assembly="umbraco" type="SearchForTemplate"/>
<notFound assembly="umbraco" type="SearchForProfile"/>
<notFound assembly="umbraco" type="handle404"/>
<notFound assembly="umbraco" type="handle404" last="true"/>
</NotFoundHandlers>
+1 -1
View File
@@ -3,5 +3,5 @@
<notFound assembly="umbraco" type="SearchForAlias" />
<notFound assembly="umbraco" type="SearchForTemplate"/>
<notFound assembly="umbraco" type="SearchForProfile"/>
<notFound assembly="umbraco" type="handle404"/>
<notFound assembly="umbraco" type="handle404" last="true"/>
</NotFoundHandlers>
@@ -1,10 +1,10 @@
using System.Linq;
using System.Web.Mvc;
using umbraco.cms.businesslogic.member;
using Umbraco.Web.Models;
using Umbraco.Web.Mvc;
using Umbraco.Web.UmbracoModels;
namespace Umbraco.Web.UmbracoControllers
namespace Umbraco.Web.Controllers
{
public class LoginController : SurfaceController
{
@@ -0,0 +1,34 @@
using System.Linq;
using System.Web.Mvc;
using umbraco.cms.businesslogic.member;
using Umbraco.Web.Models;
using Umbraco.Web.Mvc;
namespace Umbraco.Web.Controllers
{
public class LoginStatusController : SurfaceController
{
[HttpPost]
public ActionResult HandleLogout([Bind(Prefix = "loginStatusModel")]LoginStatusModel model)
{
// TODO: Use new Member API
if (ModelState.IsValid)
{
if (Member.IsLoggedOn())
{
var member = Member.GetCurrentMember();
if (member != null)
{
var memberId = member.Id;
Member.RemoveMemberFromCache(memberId);
Member.ClearMemberFromClient(memberId);
}
}
return Redirect("/");
}
return CurrentUmbracoPage();
}
}
}
@@ -0,0 +1,50 @@
using System.Linq;
using System.Web.Mvc;
using System.Xml;
using umbraco.cms.businesslogic.member;
using Umbraco.Web.Models;
using Umbraco.Web.Mvc;
namespace Umbraco.Web.Controllers
{
public class ProfileController : SurfaceController
{
[HttpPost]
public ActionResult HandleUpdateProfile([Bind(Prefix="profileModel")]ProfileModel model)
{
//TODO: Use new Member API
if (ModelState.IsValid)
{
var member = Member.GetCurrentMember();
if (member != null)
{
if (model.Name != null)
{
member.Text = model.Name;
}
member.Email = model.Email;
member.LoginName = model.Email;
if (model.MemberProperties != null)
{
foreach (var property in model.MemberProperties.Where(p => p.Value != null))
{
member.getProperty(property.Alias).Value = property.Value;
}
}
member.Save();
member.XmlGenerate(new XmlDocument());
Member.AddMemberToCache(member);
Response.Redirect("/");
}
}
return CurrentUmbracoPage();
}
}
}
@@ -3,10 +3,10 @@ using System.Web.Mvc;
using System.Xml;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.member;
using Umbraco.Web.Models;
using Umbraco.Web.Mvc;
using Umbraco.Web.UmbracoModels;
namespace Umbraco.Web.UmbracoControllers
namespace Umbraco.Web.Controllers
{
public class RegisterController : SurfaceController
{
@@ -21,13 +21,22 @@ namespace Umbraco.Web.UmbracoControllers
var mt = MemberType.GetByAlias(model.MemberTypeAlias) ?? MemberType.MakeNew(user, model.MemberTypeAlias);
var member = Member.MakeNew(model.Email, mt, user);
if (model.Name != null)
{
member.Text = model.Name;
}
member.Email = model.Email;
member.LoginName = model.Email;
member.Password = model.Password;
foreach (var property in model.MemberProperties)
if (model.MemberProperties != null)
{
member.getProperty(property.Alias).Value = property.Value;
foreach (var property in model.MemberProperties.Where(p => p.Value != null))
{
member.getProperty(property.Alias).Value = property.Value;
}
}
member.Save();
@@ -236,10 +236,11 @@ namespace Umbraco.Web.Models
}
//get the data type id for the current property
var dataType = Umbraco.Core.PublishedContentHelper.GetDataType(
var dataType = PublishedContentHelper.GetDataType(
ApplicationContext.Current,
userProperty.DocumentTypeAlias,
userProperty.Alias);
userProperty.Alias,
ItemType);
//convert the string value to a known type
var converted = Umbraco.Core.PublishedContentHelper.ConvertPropertyValue(result, dataType, userProperty.DocumentTypeAlias, userProperty.Alias);
@@ -1,7 +1,6 @@
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace Umbraco.Web.UmbracoModels
namespace Umbraco.Web.Models
{
public class LoginModel
{
@@ -0,0 +1,28 @@
using umbraco.cms.businesslogic.member;
namespace Umbraco.Web.Models
{
public class LoginStatusModel
{
public LoginStatusModel()
{
//TODO Use new Member API
if (Member.IsLoggedOn())
{
var member = Member.GetCurrentMember();
if (member != null)
{
this.Name = member.Text;
this.Username = member.LoginName;
this.Email = member.Email;
this.IsLoggedIn = true;
}
}
}
public string Name { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public bool IsLoggedIn { get; set; }
}
}
+64
View File
@@ -0,0 +1,64 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using umbraco.cms.businesslogic.member;
namespace Umbraco.Web.Models
{
public class ProfileModel
{
public ProfileModel()
{
if (Member.IsLoggedOn())
{
//TODO Use new Member API
var member = Member.GetCurrentMember();
if (member != null)
{
this.Name = member.Text;
this.Email = member.Email;
this.MemberProperties = new List<UmbracoProperty>();
var memberType = MemberType.GetByAlias(member.ContentType.Alias);
var memberTypeProperties = memberType.PropertyTypes.ToList();
if (memberTypeProperties.Where(memberType.MemberCanEdit).Any())
{
memberTypeProperties = memberTypeProperties.Where(memberType.MemberCanEdit).ToList();
}
foreach (var prop in memberTypeProperties)
{
var value = string.Empty;
var propValue = member.getProperty(prop.Alias);
if (propValue != null)
{
value = propValue.Value.ToString();
}
this.MemberProperties.Add(new UmbracoProperty
{
Alias = prop.Alias,
Name = prop.Name,
Value = value
});
}
}
}
}
[Required]
[RegularExpression(@"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
ErrorMessage = "Please enter a valid e-mail address")]
public string Email { get; set; }
public string Name { get; set; }
public string MemberTypeAlias { get; set; }
public List<UmbracoProperty> MemberProperties { get; set; }
}
}
+53
View File
@@ -0,0 +1,53 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using umbraco.cms.businesslogic.member;
namespace Umbraco.Web.Models
{
public class RegisterModel
{
public RegisterModel()
{
this.MemberTypeAlias = "UmbracoMember";
var memberType = MemberType.GetByAlias(this.MemberTypeAlias);
if (memberType != null)
{
this.MemberProperties = new List<UmbracoProperty>();
var memberTypeProperties = memberType.PropertyTypes.ToList();
if (memberTypeProperties.Where(memberType.MemberCanEdit).Any())
{
memberTypeProperties = memberTypeProperties.Where(memberType.MemberCanEdit).ToList();
}
foreach (var prop in memberTypeProperties)
{
this.MemberProperties.Add(new UmbracoProperty
{
Alias = prop.Alias,
Name = prop.Name,
Value = string.Empty
});
}
}
}
[Required]
[RegularExpression(@"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
ErrorMessage = "Please enter a valid e-mail address")]
public string Email { get; set; }
[Required]
public string Password { get; set; }
public string Name { get; set; }
public string MemberTypeAlias { get; set; }
public List<UmbracoProperty> MemberProperties { get; set; }
}
}
+6 -1
View File
@@ -34,8 +34,13 @@ namespace Umbraco.Web.Mvc
//ensure TempData and ViewData is copied across
foreach (var d in context.Controller.ViewData)
routeDef.Controller.ViewData[d.Key] = d.Value;
routeDef.Controller.TempData = context.Controller.TempData;
//We cannot simply merge the temp data because during controller execution it will attempt to 'load' temp data
// but since it has not been saved, there will be nothing to load and it will revert to nothing, so the trick is
// to Save the state of the temp data first then it will automatically be picked up.
// http://issues.umbraco.org/issue/U4-1339
context.Controller.TempData.Save(context, ((Controller)context.Controller).TempDataProvider);
using (DisposableTimer.TraceDuration<UmbracoPageResult>("Executing Umbraco RouteDefinition controller", "Finished"))
{
try
@@ -153,7 +153,10 @@ namespace Umbraco.Web
//Here we need to put the value through the IPropertyEditorValueConverter's
//get the data type id for the current property
var dataType = PublishedContentHelper.GetDataType(ApplicationContext.Current, doc.DocumentTypeAlias, alias);
var dataType = PublishedContentHelper.GetDataType(
ApplicationContext.Current, doc.DocumentTypeAlias, alias,
doc.ItemType);
//convert the string value to a known type
var converted = PublishedContentHelper.ConvertPropertyValue(p.Value, dataType, doc.DocumentTypeAlias, alias);
return converted.Success
@@ -188,7 +191,7 @@ namespace Umbraco.Web
//before we try to convert it manually, lets see if the PropertyEditorValueConverter does this for us
//Here we need to put the value through the IPropertyEditorValueConverter's
//get the data type id for the current property
var dataType = PublishedContentHelper.GetDataType(ApplicationContext.Current, prop.DocumentTypeAlias, alias);
var dataType = PublishedContentHelper.GetDataType(ApplicationContext.Current, prop.DocumentTypeAlias, alias, prop.ItemType);
//convert the value to a known type
var converted = PublishedContentHelper.ConvertPropertyValue(p.Value, dataType, prop.DocumentTypeAlias, alias);
object parsedLinksVal;
+16 -5
View File
@@ -88,14 +88,25 @@ namespace Umbraco.Web.Routing
#region Utilities
private bool FindByUrlAliasEnabled
private static bool FindByUrlAliasEnabled
{
get
{
var hasFinder = ContentFinderResolver.Current.ContainsType<ContentFinderByUrlAlias>();
var hasHandler = ContentFinderResolver.Current.ContainsType<ContentFinderByNotFoundHandlers>()
&& NotFoundHandlerHelper.CustomHandlerTypes.Contains(typeof(global::umbraco.SearchForAlias));
return hasFinder || hasHandler;
// finder
if (ContentFinderResolver.Current.ContainsType<ContentFinderByUrlAlias>())
return true;
// handler wrapped into a finder
if (ContentFinderResolver.Current.ContainsType<ContentFinderByNotFoundHandler<global::umbraco.SearchForAlias>>())
return true;
// handler wrapped into special finder
if (ContentFinderResolver.Current.ContainsType<ContentFinderByNotFoundHandlers>()
&& NotFoundHandlerHelper.IsNotFoundHandlerEnabled<global::umbraco.SearchForAlias>())
return true;
// anything else, we can't detect
return false;
}
}
@@ -29,115 +29,77 @@ namespace Umbraco.Web.Routing
#region Copied over and adapted from presentation.requestHandler
void HandlePageNotFound(PublishedContentRequest docRequest)
private static void HandlePageNotFound(PublishedContentRequest docRequest)
{
var url = NotFoundHandlerHelper.GetLegacyUrlForNotFoundHandlers();
LogHelper.Debug<ContentFinderByNotFoundHandlers>("Running for legacy url='{0}'.", () => url);
foreach (var handler in GetNotFoundHandlers())
foreach (var handler in NotFoundHandlerHelper.GetNotFoundHandlers())
{
IContentFinder finder = null;
var handlerName = handler.GetType().FullName;
LogHelper.Debug<ContentFinderByNotFoundHandlers>("Handler '{0}'.", () => handlerName);
// replace with our own implementation
if (handler is global::umbraco.SearchForAlias)
finder = new ContentFinderByUrlAlias();
else if (handler is global::umbraco.SearchForProfile)
finder = new ContentFinderByProfile();
else if (handler is global::umbraco.SearchForTemplate)
finder = new ContentFinderByNiceUrlAndTemplate();
else if (handler is global::umbraco.handle404)
finder = new ContentFinderByLegacy404();
var finder = NotFoundHandlerHelper.SubsituteFinder(handler);
if (finder != null)
{
var finderName = finder.GetType().FullName;
LogHelper.Debug<ContentFinderByNotFoundHandlers>("Replace handler '{0}' by new finder '{1}'.", () => handlerName, () => finderName);
if (finder.TryFindContent(docRequest))
{
// do NOT set docRequest.PublishedContent again here as
// it would clear any template that the finder might have set
LogHelper.Debug<ContentFinderByNotFoundHandlers>("Finder '{0}' found node with id={1}.", () => finderName, () => docRequest.PublishedContent.Id);
if (docRequest.Is404)
LogHelper.Debug<ContentFinderByNotFoundHandlers>("Finder '{0}' set status to 404.", () => finderName);
// if we found a document, break, don't look at more handler -- we're done
break;
}
// can't find a document => continue with other handlers
if (finder.TryFindContent(docRequest) == false)
continue;
// if we did not find a document, continue, look at other handlers
continue;
}
// found a document => break, don't run other handlers, we're done
// else it's a legacy handler, run
// in theory an IContentFinder can return true yet set no document
// but none of the substitued finders (see SubstituteFinder) do it.
if (handler.Execute(url) && handler.redirectID > 0)
{
var redirectId = handler.redirectID;
docRequest.PublishedContent = docRequest.RoutingContext.UmbracoContext.ContentCache.GetById(redirectId);
// do NOT set docRequest.PublishedContent again here
// as it would clear any template that the finder might have set
if (!docRequest.HasPublishedContent)
{
LogHelper.Debug<ContentFinderByNotFoundHandlers>("Handler '{0}' found node with id={1} which is not valid.", () => handlerName, () => redirectId);
break;
}
LogHelper.Debug<ContentFinderByNotFoundHandlers>("Finder '{0}' found node with id={1}.", () => finderName, () => docRequest.PublishedContent.Id);
if (docRequest.Is404)
LogHelper.Debug<ContentFinderByNotFoundHandlers>("Finder '{0}' set status to 404.", () => finderName);
LogHelper.Debug<ContentFinderByNotFoundHandlers>("Handler '{0}' found valid node with id={1}.", () => handlerName, () => redirectId);
if (docRequest.RoutingContext.UmbracoContext.HttpContext.Response.StatusCode == 404)
{
LogHelper.Debug<ContentFinderByNotFoundHandlers>("Handler '{0}' set status code to 404.", () => handlerName);
docRequest.Is404 = true;
}
//// check for caching
//if (handler.CacheUrl)
//{
// if (url.StartsWith("/"))
// url = "/" + url;
// var cacheKey = (currentDomain == null ? "" : currentDomain.Name) + url;
// var culture = currentDomain == null ? null : currentDomain.Language.CultureAlias;
// SetCache(cacheKey, new CacheEntry(handler.redirectID.ToString(), culture));
// HttpContext.Current.Trace.Write("NotFoundHandler",
// string.Format("Added to cache '{0}', {1}.", url, handler.redirectID));
//}
// if we found a document, break, don't look at more handler -- we're done
LogHelper.Debug<ContentFinderByNotFoundHandlers>("Handler '{0}' found valid node with id={1}.", () => handlerName, () => docRequest.PublishedContent.Id);
break;
}
// if we did not find a document, continue, look at other handlers
// else it's a legacy handler: run
// can't find a document => continue with other handlers
if (handler.Execute(url) == false || handler.redirectID <= 0)
continue;
// found a document ID => ensure it's a valid document
var redirectId = handler.redirectID;
docRequest.PublishedContent = docRequest.RoutingContext.UmbracoContext.ContentCache.GetById(redirectId);
if (docRequest.HasPublishedContent == false)
{
// the handler said it could handle the url, and returned a content ID
// yet that content ID is invalid... should we run the other handlers?
// I don't think so, not here, let the "last chance" finder take care.
// so, break.
LogHelper.Debug<ContentFinderByNotFoundHandlers>("Handler '{0}' found node with id={1} which is not valid.", () => handlerName, () => redirectId);
break;
}
// found a valid document => break, don't run other handlers, we're done
LogHelper.Debug<ContentFinderByNotFoundHandlers>("Handler '{0}' found valid node with id={1}.", () => handlerName, () => redirectId);
if (docRequest.RoutingContext.UmbracoContext.HttpContext.Response.StatusCode == 404)
{
LogHelper.Debug<ContentFinderByNotFoundHandlers>("Handler '{0}' set status code to 404.", () => handlerName);
docRequest.Is404 = true;
}
break;
}
}
IEnumerable<INotFoundHandler> GetNotFoundHandlers()
{
// instanciate new handlers
// using definition cache
var handlers = new List<INotFoundHandler>();
foreach (var type in NotFoundHandlerHelper.CustomHandlerTypes)
{
try
{
var handler = Activator.CreateInstance(type) as INotFoundHandler;
if (handler != null)
handlers.Add(handler);
}
catch (Exception e)
{
LogHelper.Error<ContentFinderByNotFoundHandlers>(string.Format("Error instanciating handler {0}, ignoring.", type.FullName), e);
}
}
return handlers;
}
#endregion
}
}
@@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using umbraco.interfaces;
namespace Umbraco.Web.Routing
{
/// <summary>
/// Provides an implementation of <see cref="IContentFinder"/> that runs legacy <c>INotFoundHandler</c> in "last chance" situation.
/// </summary>
public class ContentLastChanceFinderByNotFoundHandlers : IContentFinder
{
// notes
//
// at the moment we load the legacy INotFoundHandler
// excluding those that have been replaced by proper finders,
// and run them.
/// <summary>
/// Tries to find and assign an Umbraco document to a <c>PublishedContentRequest</c>.
/// </summary>
/// <param name="docRequest">The <c>PublishedContentRequest</c>.</param>
/// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
public bool TryFindContent(PublishedContentRequest docRequest)
{
HandlePageNotFound(docRequest);
return docRequest.HasPublishedContent;
}
#region Copied over and adapted from presentation.requestHandler
private static void HandlePageNotFound(PublishedContentRequest docRequest)
{
var url = NotFoundHandlerHelper.GetLegacyUrlForNotFoundHandlers();
LogHelper.Debug<ContentLastChanceFinderByNotFoundHandlers>("Running for legacy url='{0}'.", () => url);
var handler = NotFoundHandlerHelper.GetNotFoundLastChanceHandler();
var handlerName = handler.GetType().FullName;
LogHelper.Debug<ContentLastChanceFinderByNotFoundHandlers>("Handler '{0}'.", () => handlerName);
var finder = NotFoundHandlerHelper.SubsituteFinder(handler);
if (finder != null)
{
var finderName = finder.GetType().FullName;
LogHelper.Debug<ContentLastChanceFinderByNotFoundHandlers>("Replace handler '{0}' by new finder '{1}'.", () => handlerName, () => finderName);
// can't find a document => exit
if (finder.TryFindContent(docRequest) == false)
return;
// found a document => we're done
// in theory an IContentFinder can return true yet set no document
// but none of the substitued finders (see SubstituteFinder) do it.
// do NOT set docRequest.PublishedContent again here
// as it would clear any template that the finder might have set
LogHelper.Debug<ContentLastChanceFinderByNotFoundHandlers>("Finder '{0}' found node with id={1}.", () => finderName, () => docRequest.PublishedContent.Id);
if (docRequest.Is404)
LogHelper.Debug<ContentLastChanceFinderByNotFoundHandlers>("Finder '{0}' set status to 404.", () => finderName);
LogHelper.Debug<ContentLastChanceFinderByNotFoundHandlers>("Handler '{0}' found valid node with id={1}.", () => handlerName, () => docRequest.PublishedContent.Id);
return;
}
// else it's a legacy handler, run
// can't find a document => exit
if (handler.Execute(url) == false || handler.redirectID <= 0)
return;
// found a document ID => ensure it's a valid document
var redirectId = handler.redirectID;
docRequest.PublishedContent = docRequest.RoutingContext.UmbracoContext.ContentCache.GetById(redirectId);
if (docRequest.HasPublishedContent == false)
{
// the handler said it could handle the url, and returned a content ID
// yet that content ID is invalid... exit.
LogHelper.Debug<ContentLastChanceFinderByNotFoundHandlers>("Handler '{0}' found node with id={1} which is not valid.", () => handlerName, () => redirectId);
return;
}
// found a valid document => return
LogHelper.Debug<ContentLastChanceFinderByNotFoundHandlers>("Handler '{0}' found valid node with id={1}.", () => handlerName, () => redirectId);
if (docRequest.RoutingContext.UmbracoContext.HttpContext.Response.StatusCode == 404)
{
LogHelper.Debug<ContentLastChanceFinderByNotFoundHandlers>("Handler '{0}' set status code to 404.", () => handlerName);
docRequest.Is404 = true;
}
}
#endregion
}
}
@@ -1,9 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml;
using System.Reflection;
using Umbraco.Core;
using Umbraco.Core.Logging;
using umbraco.interfaces;
namespace Umbraco.Web.Routing
{
@@ -36,14 +39,14 @@ namespace Umbraco.Web.Routing
return url;
// code from requestModule.UmbracoRewrite
string tmp = httpContext.Request.Path.ToLower();
var tmp = httpContext.Request.Path.ToLower();
// note: requestModule.UmbracoRewrite also did some stripping of &umbPage
// from the querystring... that was in v3.x to fix some issues with pre-forms
// auth. Paul Sterling confirmed in jan. 2013 that we can get rid of it.
// code from requestHandler.cleanUrl
string root = Core.IO.SystemDirectories.Root.ToLower();
var root = Core.IO.SystemDirectories.Root.ToLower();
if (!string.IsNullOrEmpty(root) && tmp.StartsWith(root))
tmp = tmp.Substring(root.Length);
tmp = tmp.TrimEnd('/');
@@ -55,7 +58,7 @@ namespace Umbraco.Web.Routing
// code from UmbracoDefault.Page_PreInit
if (tmp != "" && httpContext.Request["umbPageID"] == null)
{
string tryIntParse = tmp.Replace("/", "").Replace(".aspx", string.Empty);
var tryIntParse = tmp.Replace("/", "").Replace(".aspx", string.Empty);
int result;
if (int.TryParse(tryIntParse, out result))
tmp = tmp.Replace(".aspx", string.Empty);
@@ -77,7 +80,8 @@ namespace Umbraco.Web.Routing
return tmp;
}
static IEnumerable<Type> _customHandlerTypes;
private static IEnumerable<Type> _customHandlerTypes;
private static Type _customLastChanceHandlerType;
static void InitializeNotFoundHandlers()
{
@@ -87,6 +91,8 @@ namespace Umbraco.Web.Routing
LogHelper.Debug<NotFoundHandlerHelper>("Registering custom handlers.");
var customHandlerTypes = new List<Type>();
Type customLastChanceHandlerType = null;
var hasLast = false;
var customHandlers = new XmlDocument();
customHandlers.Load(Core.IO.IOHelper.MapPath(Core.IO.SystemFiles.NotFoundhandlersConfig));
@@ -96,12 +102,23 @@ namespace Umbraco.Web.Routing
var assemblyName = n.Attributes.GetNamedItem("assembly").Value;
var typeName = n.Attributes.GetNamedItem("type").Value;
string ns = assemblyName;
var ns = assemblyName;
var nsAttr = n.Attributes.GetNamedItem("namespace");
if (nsAttr != null && !string.IsNullOrWhiteSpace(nsAttr.Value))
if (nsAttr != null && string.IsNullOrWhiteSpace(nsAttr.Value) == false)
ns = nsAttr.Value;
LogHelper.Debug<NotFoundHandlerHelper>("Registering '{0}.{1},{2}'.", () => ns, () => typeName, () => assemblyName);
var lcAttr = n.Attributes.GetNamedItem("last");
var last = lcAttr != null && lcAttr.Value != null && lcAttr.Value.InvariantEquals("true");
if (last) // there can only be one last chance handler in the config file
{
if (hasLast)
throw new Exception();
hasLast = true;
}
LogHelper.Debug<NotFoundHandlerHelper>("Registering '{0}.{1},{2}'{3}", () => ns, () => typeName, () => assemblyName,
() => last ? " (last)." : ".");
Type type = null;
try
@@ -114,19 +131,79 @@ namespace Umbraco.Web.Routing
LogHelper.Error<NotFoundHandlerHelper>("Error registering handler, ignoring.", e);
}
if (type != null)
if (type == null) continue;
if (last)
_customLastChanceHandlerType = type;
else
customHandlerTypes.Add(type);
}
_customHandlerTypes = customHandlerTypes;
_customHandlerTypes = customHandlerTypes.ToArray();
}
public static IEnumerable<Type> CustomHandlerTypes
public static IEnumerable<INotFoundHandler> GetNotFoundHandlers()
{
get
// instanciate new handlers
// using definition cache
var handlers = new List<INotFoundHandler>();
foreach (var type in _customHandlerTypes)
{
return _customHandlerTypes;
try
{
var handler = Activator.CreateInstance(type) as INotFoundHandler;
if (handler != null)
handlers.Add(handler);
}
catch (Exception e)
{
LogHelper.Error<ContentFinderByNotFoundHandlers>(string.Format("Error instanciating handler {0}, ignoring.", type.FullName), e);
}
}
return handlers;
}
public static bool IsNotFoundHandlerEnabled<T>()
{
return _customHandlerTypes.Contains(typeof (T));
}
public static INotFoundHandler GetNotFoundLastChanceHandler()
{
if (_customLastChanceHandlerType == null) return null;
try
{
var handler = Activator.CreateInstance(_customLastChanceHandlerType) as INotFoundHandler;
if (handler != null)
return handler;
}
catch (Exception e)
{
LogHelper.Error<ContentFinderByNotFoundHandlers>(string.Format("Error instanciating handler {0}, ignoring.", _customLastChanceHandlerType.FullName), e);
}
return null;
}
public static IContentFinder SubsituteFinder(INotFoundHandler handler)
{
IContentFinder finder = null;
if (handler is global::umbraco.SearchForAlias)
finder = new ContentFinderByUrlAlias();
else if (handler is global::umbraco.SearchForProfile)
finder = new ContentFinderByProfile();
else if (handler is global::umbraco.SearchForTemplate)
finder = new ContentFinderByNiceUrlAndTemplate();
else if (handler is global::umbraco.handle404)
finder = new ContentFinderByLegacy404();
return finder;
}
}
}
+10 -4
View File
@@ -298,6 +298,8 @@
<Compile Include="Configuration\WebRouting.cs" />
<Compile Include="Editors\AuthenticationController.cs" />
<Compile Include="Editors\ContentController.cs" />
<Compile Include="Controllers\ProfileController.cs" />
<Compile Include="Controllers\LoginStatusController.cs" />
<Compile Include="Editors\ContentPostValidateAttribute.cs" />
<Compile Include="Editors\DataTypeController.cs" />
<Compile Include="Editors\DataTypeValidateAttribute.cs" />
@@ -343,9 +345,12 @@
<Compile Include="Editors\ContentControllerBase.cs" />
<Compile Include="Editors\ContentTypeController.cs" />
<Compile Include="Editors\LegacyController.cs" />
<Compile Include="UmbracoControllers\RegisterController.cs" />
<Compile Include="UmbracoModels\RegisterModel.cs" />
<Compile Include="UmbracoModels\LoginModel.cs" />
<Compile Include="Controllers\RegisterController.cs" />
<Compile Include="Models\ProfileModel.cs" />
<Compile Include="Models\LoginStatusModel.cs" />
<Compile Include="Routing\ContentLastChanceFinderByNotFoundHandlers.cs" />
<Compile Include="Models\RegisterModel.cs" />
<Compile Include="Models\LoginModel.cs" />
<Compile Include="Editors\MediaTypeController.cs" />
<Compile Include="Editors\SectionController.cs" />
<Compile Include="Editors\UmbracoAuthorizedJsonController.cs" />
@@ -530,7 +535,8 @@
<Compile Include="umbraco.presentation\umbraco\settings\stylesheet\property\EditStyleSheetProperty.aspx.cs">
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="UmbracoControllers\LoginController.cs" />
<Compile Include="Controllers\LoginController.cs" />
<Compile Include="UmbracoProperty.cs" />
<Compile Include="UrlHelperExtensions.cs" />
<Compile Include="Editors\MediaController.cs" />
<Compile Include="WebApi\Binders\ContentItemBaseBinder.cs" />
+8 -2
View File
@@ -445,8 +445,14 @@ namespace Umbraco.Web
_umbracoContext = null;
//ensure not to dispose this!
Application = null;
ContentCache = null;
MediaCache = null;
//Before we set these to null but in fact these are application lifespan singletons so
//there's no reason we need to set them to null and this also caused a problem with packages
//trying to access the cache properties on RequestEnd.
//http://issues.umbraco.org/issue/U4-2734
//http://our.umbraco.org/projects/developer-tools/301-url-tracker/version-2/44327-Issues-with-URL-Tracker-in-614
//ContentCache = null;
//MediaCache = null;
}
}
}
@@ -1,28 +0,0 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace Umbraco.Web.UmbracoModels
{
public class RegisterModel
{
[Required]
[RegularExpression(@"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
ErrorMessage = "Please enter a valid e-mail address")]
public string Email { get; set; }
[Required]
public string Password { get; set; }
public string MemberTypeAlias { get; set; }
public List<UmbracoProperty> MemberProperties { get; set; }
}
public class UmbracoProperty
{
public string Alias { get; set; }
public string Value { get; set; }
public string Name { get; set; }
}
}
+9
View File
@@ -0,0 +1,9 @@
namespace Umbraco.Web
{
public class UmbracoProperty
{
public string Alias { get; set; }
public string Value { get; set; }
public string Name { get; set; }
}
}
+23 -15
View File
@@ -313,23 +313,31 @@ namespace Umbraco.Web
typeof(DefaultUrlProvider)
);
// the legacy 404 will run from within ContentFinderByNotFoundHandlers below
// so for the time being there is no last chance finder
ContentLastChanceFinderResolver.Current = new ContentLastChanceFinderResolver();
ContentLastChanceFinderResolver.Current = new ContentLastChanceFinderResolver(
// handled by ContentLastChanceFinderByNotFoundHandlers for the time being
// soon as we get rid of INotFoundHandler support, we must enable this
//new ContentFinderByLegacy404()
// implement INotFoundHandler support... remove once we get rid of it
new ContentLastChanceFinderByNotFoundHandlers());
ContentFinderResolver.Current = new ContentFinderResolver(
// add all known resolvers in the correct order, devs can then modify this list
// on application startup either by binding to events or in their own global.asax
typeof (ContentFinderByPageIdQuery),
typeof (ContentFinderByNiceUrl),
typeof (ContentFinderByIdPath),
// these will be handled by ContentFinderByNotFoundHandlers
// so they can be enabled/disabled even though resolvers are not public yet
//typeof (ContentFinderByNiceUrlAndTemplate),
//typeof (ContentFinderByProfile),
//typeof (ContentFinderByUrlAlias),
typeof (ContentFinderByNotFoundHandlers)
);
// all built-in finders in the correct order, devs can then modify this list
// on application startup via an application event handler.
typeof (ContentFinderByPageIdQuery),
typeof (ContentFinderByNiceUrl),
typeof (ContentFinderByIdPath),
// these will be handled by ContentFinderByNotFoundHandlers so they can be enabled/disabled
// via the config file... soon as we get rid of INotFoundHandler support, we must enable
// them here.
//typeof (ContentFinderByNiceUrlAndTemplate),
//typeof (ContentFinderByProfile),
//typeof (ContentFinderByUrlAlias),
// implement INotFoundHandler support... remove once we get rid of it
typeof (ContentFinderByNotFoundHandlers)
);
SiteDomainHelperResolver.Current = new SiteDomainHelperResolver(new SiteDomainHelper());
@@ -8,14 +8,14 @@ namespace umbraco.editorControls.imagecropper
public override XmlNode ToXMl(XmlDocument data)
{
if (Value.ToString() != "") {
XmlDocument xd = new XmlDocument();
if (Value != null && Value.ToString() != "")
{
var xd = new XmlDocument();
xd.LoadXml(Value.ToString());
return data.ImportNode(xd.DocumentElement, true);
} else {
return base.ToXMl(data);
}
return base.ToXMl(data);
}
}
}