diff --git a/.hgignore b/.hgignore
index a6ddc03595..980273f4f7 100644
--- a/.hgignore
+++ b/.hgignore
@@ -47,5 +47,6 @@ src/Umbraco.Tests/config/trees.config
src/Umbraco.Web.UI/web.config
*.orig
src/Umbraco.Tests/config/404handlers.config
-src/Umbraco.Web.UI/Views/*
+src/Umbraco.Web.UI/Views/*.cshtml
+src/Umbraco.Web.UI/Views/*.vbhtml
src/Umbraco.Tests/config/umbracoSettings.config
diff --git a/build/Build.bat b/build/Build.bat
index 76cf1b11fe..aca687fdcc 100644
--- a/build/Build.bat
+++ b/build/Build.bat
@@ -1,2 +1,9 @@
+@ECHO OFF
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "Build.proj"
-REM pause
\ No newline at end of file
+
+if ERRORLEVEL 1 goto :showerror
+
+goto :EOF
+
+:showerror
+pause
\ No newline at end of file
diff --git a/src/Umbraco.Core/ActivatorHelper.cs b/src/Umbraco.Core/ActivatorHelper.cs
new file mode 100644
index 0000000000..88ec01ae35
--- /dev/null
+++ b/src/Umbraco.Core/ActivatorHelper.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace Umbraco.Core
+{
+ ///
+ /// Helper methods for Activation
+ ///
+ internal static class ActivatorHelper
+ {
+ ///
+ /// Creates an instance of a type using that type's default constructor.
+ ///
+ ///
+ ///
+ public static T CreateInstance() where T : class, new()
+ {
+ return Activator.CreateInstance(typeof(T)) as T;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Configuration/GlobalSettings.cs b/src/Umbraco.Core/Configuration/GlobalSettings.cs
index f330049fb7..424e7b2f24 100644
--- a/src/Umbraco.Core/Configuration/GlobalSettings.cs
+++ b/src/Umbraco.Core/Configuration/GlobalSettings.cs
@@ -115,7 +115,7 @@ namespace Umbraco.Core.Configuration
/// We will use the 'Path' (default ~/umbraco) to create it but since it cannot contain '/' and people may specify a path of ~/asdf/asdf/admin
/// we will convert the '/' to '-' and use that as the path. its a bit lame but will work.
///
- internal static string MvcArea
+ internal static string UmbracoMvcArea
{
get
{
diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings.cs b/src/Umbraco.Core/Configuration/UmbracoSettings.cs
index 2c7e2a00d3..8de810f588 100644
--- a/src/Umbraco.Core/Configuration/UmbracoSettings.cs
+++ b/src/Umbraco.Core/Configuration/UmbracoSettings.cs
@@ -1145,6 +1145,71 @@ namespace Umbraco.Core.Configuration
}
}
+ ///
+ /// Enables MVC, and at the same time disable webform masterpage templates.
+ /// This ensure views are automaticly created instead of masterpages.
+ /// Views are display in the tree instead of masterpages and a MVC template editor
+ /// is used instead of the masterpages editor
+ ///
+ /// true if umbraco defaults to using MVC views for templating, otherwise false.
+
+ private static bool? _enableMvc;
+ public static bool EnableMvcSupport
+ {
+ get
+ {
+ if (_enableMvc == null)
+ {
+ try
+ {
+ bool enableMvc = false;
+ string value = GetKey("/settings/templates/enableMvcSupport");
+ if (value != null)
+ if (bool.TryParse(value, out enableMvc))
+ _enableMvc = enableMvc;
+ }
+ catch (Exception ex)
+ {
+ Trace.WriteLine("Could not load /settings/templates/enableMvcSupport from umbracosettings.config:\r\n {0}",
+ ex.Message);
+
+ _enableMvc = false;
+ }
+ }
+ return _enableMvc == true;
+ }
+ }
+
+ private static string[] _mvcViewExtensions;
+ public static string[] MvcViewExtensions
+ {
+ get
+ {
+ string[] defaultValue = "cshtml".Split(',');
+
+ if (_mvcViewExtensions == null)
+ {
+ try
+ {
+ string value = GetKey("/settings/templates/mvcViewExtensions");
+ if (!string.IsNullOrEmpty(value))
+ _mvcViewExtensions = value.Split(',');
+ else
+ _mvcViewExtensions = defaultValue;
+ }
+ catch (Exception ex)
+ {
+ Trace.WriteLine("Could not load /settings/templates/mvcViewExtensions from umbracosettings.config:\r\n {0}",
+ ex.Message);
+
+ _mvcViewExtensions = defaultValue;
+ }
+ }
+
+ return _mvcViewExtensions;
+ }
+ }
+
///
/// Configuration regarding webservices
///
diff --git a/src/Umbraco.Core/IO/IOHelper.cs b/src/Umbraco.Core/IO/IOHelper.cs
index 8a3a0688d5..f718483d0f 100644
--- a/src/Umbraco.Core/IO/IOHelper.cs
+++ b/src/Umbraco.Core/IO/IOHelper.cs
@@ -165,6 +165,23 @@ namespace Umbraco.Core.IO
return true;
}
+ public static bool ValidateEditPath(string filePath, string[] validDirs)
+ {
+ foreach (var dir in validDirs)
+ {
+ var validDir = dir;
+ if (!filePath.StartsWith(MapPath(SystemDirectories.Root)))
+ filePath = MapPath(filePath);
+ if (!validDir.StartsWith(MapPath(SystemDirectories.Root)))
+ validDir = MapPath(validDir);
+
+ if (filePath.StartsWith(validDir))
+ return true;
+ }
+
+ throw new FileSecurityException(String.Format("The filepath '{0}' is not within an allowed directory for this type of files", filePath.Replace(MapPath(SystemDirectories.Root), "")));
+ }
+
public static bool ValidateFileExtension(string filePath, List validFileExtensions)
{
if (!filePath.StartsWith(MapPath(SystemDirectories.Root)))
diff --git a/src/Umbraco.Core/IThumbnailProvider.cs b/src/Umbraco.Core/IThumbnailProvider.cs
index 0948f1d8eb..c05f50bb62 100644
--- a/src/Umbraco.Core/IThumbnailProvider.cs
+++ b/src/Umbraco.Core/IThumbnailProvider.cs
@@ -7,7 +7,6 @@ namespace Umbraco.Core
{
public interface IThumbnailProvider
{
- int Priority { get; }
bool CanProvideThumbnail(string fileUrl);
string GetThumbnailUrl(string fileUrl);
}
diff --git a/src/Umbraco.Core/Mandate.cs b/src/Umbraco.Core/Mandate.cs
new file mode 100644
index 0000000000..54d589b90a
--- /dev/null
+++ b/src/Umbraco.Core/Mandate.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Umbraco.Core
+{
+ ///
+ /// Helper class for mandating values, for example on method parameters.
+ ///
+ internal static class Mandate
+ {
+ ///
+ /// Mandates that the specified parameter is not null.
+ ///
+ /// The value.
+ /// Name of the param.
+ /// If is null.
+ public static void ParameterNotNull(T value, string paramName) where T : class
+ {
+ That(value != null, () => new ArgumentNullException(paramName));
+ }
+
+
+ ///
+ /// Mandates that the specified parameter is not null.
+ ///
+ /// The value.
+ /// Name of the param.
+ /// If is null or whitespace.
+ public static void ParameterNotNullOrEmpty(string value, string paramName)
+ {
+ That(!string.IsNullOrWhiteSpace(value), () => new ArgumentNullException(paramName));
+ }
+
+ ///
+ /// Mandates that the specified sequence is not null and has at least one element.
+ ///
+ ///
+ /// The sequence.
+ /// Name of the param.
+ public static void ParameterNotNullOrEmpty(IEnumerable sequence, string paramName)
+ {
+ ParameterNotNull(sequence, paramName);
+ ParameterCondition(sequence.Any(), paramName);
+ }
+
+
+ ///
+ /// Mandates that the specified parameter matches the condition.
+ ///
+ /// The condition to check.
+ /// Name of the param.
+ /// If the condition is false.
+ public static void ParameterCondition(bool condition, string paramName)
+ {
+ ParameterCondition(condition, paramName, (string)null);
+ }
+
+ ///
+ /// Mandates that the specified parameter matches the condition.
+ ///
+ /// The condition to check.
+ /// Name of the param.
+ /// The message.
+ /// If the condition is false.
+ public static void ParameterCondition(bool condition, string paramName, string message)
+ {
+ // Warning: don't make this method have an optional message parameter (removing the other ParameterCondition overload) as it will
+ // make binaries compiled against previous Framework libs incompatible unneccesarily
+ message = message ?? "A parameter passed into a method was not a valid value";
+ That(condition, () => new ArgumentException(message, paramName));
+ }
+
+ ///
+ /// Mandates that the specified condition is true, otherwise throws an exception specified in .
+ ///
+ /// The type of the exception.
+ /// if set to true, throws exception .
+ /// An exception of type is raised if the condition is false.
+ public static void That(bool condition) where TException : Exception, new()
+ {
+ if (!condition)
+ throw ActivatorHelper.CreateInstance();
+ }
+
+ ///
+ /// Mandates that the specified condition is true, otherwise throws an exception specified in .
+ ///
+ /// The type of the exception.
+ /// if set to true, throws exception .
+ /// Deffered expression to call if the exception should be raised.
+ /// An exception of type is raised if the condition is false.
+ public static void That(bool condition, Func defer) where TException : Exception, new()
+ {
+ if (!condition)
+ {
+ throw defer.Invoke();
+ }
+
+ // Here is an example of how this method is actually called
+ //object myParam = null;
+ //Mandate.That(myParam != null,
+ // textManager => new ArgumentNullException(textManager.Get("blah", new {User = "blah"})));
+ }
+ }
+}
diff --git a/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs b/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs
index bab284c7f4..2b8d1c43c7 100644
--- a/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs
+++ b/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs
@@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Threading;
using System.Web;
namespace Umbraco.Core.ObjectResolution
{
+
internal abstract class ManyObjectsResolverBase : ResolverBase
where TResolved : class
where TResolver : class
@@ -94,6 +96,40 @@ namespace Umbraco.Core.ObjectResolution
///
protected ObjectLifetimeScope LifetimeScope { get; private set; }
+ private int _defaultPluginWeight = 10;
+
+ ///
+ /// Used in conjunction with GetSortedValues and WeightedPluginAttribute, if any of the objects
+ /// being resolved do not contain the WeightedPluginAttribute then this will be the default weight applied
+ /// to the object.
+ ///
+ protected virtual int DefaultPluginWeight
+ {
+ get { return _defaultPluginWeight; }
+ set { _defaultPluginWeight = value; }
+ }
+
+ ///
+ /// If a resolver requries that objects are resolved with a specific order using the WeightedPluginAttribute
+ /// then this method should be used instead of the Values property.
+ ///
+ ///
+ protected IEnumerable GetSortedValues()
+ {
+ var vals = Values.ToList();
+ //ensure they are sorted
+ vals.Sort((f1, f2) =>
+ {
+ Func