diff --git a/build/UmbracoVersion.txt b/build/UmbracoVersion.txt
index 35e273acdc..2a8a3618d4 100644
--- a/build/UmbracoVersion.txt
+++ b/build/UmbracoVersion.txt
@@ -1,3 +1,3 @@
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
7.4.0
-beta3
\ No newline at end of file
+beta4
\ No newline at end of file
diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs
index e4f169c8af..f385151454 100644
--- a/src/SolutionInfo.cs
+++ b/src/SolutionInfo.cs
@@ -12,4 +12,4 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.4.0")]
-[assembly: AssemblyInformationalVersion("7.4.0-beta3")]
\ No newline at end of file
+[assembly: AssemblyInformationalVersion("7.4.0-beta4")]
\ No newline at end of file
diff --git a/src/Umbraco.Core/Configuration/UmbracoVersion.cs b/src/Umbraco.Core/Configuration/UmbracoVersion.cs
index 2d2ba9ad5c..4039ab7db0 100644
--- a/src/Umbraco.Core/Configuration/UmbracoVersion.cs
+++ b/src/Umbraco.Core/Configuration/UmbracoVersion.cs
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Configuration
/// Gets the version comment (like beta or RC).
///
/// The version comment.
- public static string CurrentComment { get { return "beta3"; } }
+ public static string CurrentComment { get { return "beta4"; } }
// 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
diff --git a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs
index b5caf08dfb..2c6d66bdd7 100644
--- a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs
+++ b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs
@@ -205,6 +205,9 @@ namespace Umbraco.Web.Editors
ModelState.AddModelError("Alias", "A content type, media type or member type with this alias already exists");
}
+ //now let the external validators execute
+ EditorValidationResolver.Current.Validate(contentTypeSave, new EditorValidationErrors((key, msg) => ModelState.AddModelError(key, msg)));
+
if (ModelState.IsValid == false)
{
TContentTypeDisplay forDisplay;
diff --git a/src/Umbraco.Web/Editors/EditorValidationErrors.cs b/src/Umbraco.Web/Editors/EditorValidationErrors.cs
new file mode 100644
index 0000000000..95e5d8590a
--- /dev/null
+++ b/src/Umbraco.Web/Editors/EditorValidationErrors.cs
@@ -0,0 +1,23 @@
+using System;
+
+namespace Umbraco.Web.Editors
+{
+ ///
+ /// Used to encapsulate ModelStateDictionary, but because there are 2x this (mvc and webapi), this
+ /// is just a simple way to have one object for both
+ ///
+ internal class EditorValidationErrors
+ {
+ private readonly Action _addModelError;
+
+ public EditorValidationErrors(Action addModelError)
+ {
+ _addModelError = addModelError;
+ }
+
+ public void AddModelError(string key, string message)
+ {
+ _addModelError(key, message);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Editors/EditorValidationResolver.cs b/src/Umbraco.Web/Editors/EditorValidationResolver.cs
new file mode 100644
index 0000000000..c4c5902518
--- /dev/null
+++ b/src/Umbraco.Web/Editors/EditorValidationResolver.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Umbraco.Core.Logging;
+using Umbraco.Core.ObjectResolution;
+
+namespace Umbraco.Web.Editors
+{
+ internal class EditorValidationResolver : LazyManyObjectsResolverBase
+ {
+ public EditorValidationResolver(IServiceProvider serviceProvider, ILogger logger, Func> migrations)
+ : base(serviceProvider, logger, migrations, ObjectLifetimeScope.Application)
+ {
+ }
+
+ public virtual IEnumerable EditorValidators
+ {
+ get { return Values; }
+ }
+
+ public void Validate(object model, EditorValidationErrors editorValidations)
+ {
+ foreach (var validator in EditorValidators.Where(x => x.GetType() == x.ModelType))
+ {
+ validator.Validate(model, editorValidations);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Editors/EditorValidator.cs b/src/Umbraco.Web/Editors/EditorValidator.cs
new file mode 100644
index 0000000000..21698bd53f
--- /dev/null
+++ b/src/Umbraco.Web/Editors/EditorValidator.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace Umbraco.Web.Editors
+{
+ internal abstract class EditorValidator : IEditorValidator
+ {
+ public Type ModelType
+ {
+ get { return typeof (T); }
+ }
+
+ public abstract void Validate(object model, EditorValidationErrors editorValidations);
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Editors/IEditorValidator.cs b/src/Umbraco.Web/Editors/IEditorValidator.cs
new file mode 100644
index 0000000000..318564b1d9
--- /dev/null
+++ b/src/Umbraco.Web/Editors/IEditorValidator.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace Umbraco.Web.Editors
+{
+ internal interface IEditorValidator
+ {
+ Type ModelType { get; }
+ void Validate(object model, EditorValidationErrors editorValidations);
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Editors/ValidationHelper.cs b/src/Umbraco.Web/Editors/ValidationHelper.cs
index 7bad8ceb8c..06699c56af 100644
--- a/src/Umbraco.Web/Editors/ValidationHelper.cs
+++ b/src/Umbraco.Web/Editors/ValidationHelper.cs
@@ -1,7 +1,10 @@
using System;
using System.ComponentModel;
using System.Linq;
+using System.Web;
+using System.Web.Http.ModelBinding;
using Umbraco.Core.Models.Validation;
+using Umbraco.Web.Models.ContentEditing;
namespace Umbraco.Web.Editors
{
diff --git a/src/Umbraco.Web/Properties/AssemblyInfo.cs b/src/Umbraco.Web/Properties/AssemblyInfo.cs
index c881ba448a..89499b833e 100644
--- a/src/Umbraco.Web/Properties/AssemblyInfo.cs
+++ b/src/Umbraco.Web/Properties/AssemblyInfo.cs
@@ -35,5 +35,6 @@ using System.Security;
[assembly: InternalsVisibleTo("Umbraco.Courier.Core")]
[assembly: InternalsVisibleTo("Umbraco.Courier.Persistence")]
[assembly: InternalsVisibleTo("Umbraco.VisualStudio")]
-
+[assembly: InternalsVisibleTo("Umbraco.ModelsBuilder")]
+[assembly: InternalsVisibleTo("Umbraco.ModelsBuilder.AspNet")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
\ No newline at end of file
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 436186d3d0..b9d0be3dec 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -303,6 +303,10 @@
+
+
+
+
diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs
index 0757c6c951..1ab96a6a1b 100644
--- a/src/Umbraco.Web/WebBootManager.cs
+++ b/src/Umbraco.Web/WebBootManager.cs
@@ -44,6 +44,7 @@ using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.Publishing;
using Umbraco.Core.Services;
+using Umbraco.Web.Editors;
using GlobalSettings = Umbraco.Core.Configuration.GlobalSettings;
using ProfilingViewEngine = Umbraco.Core.Profiling.ProfilingViewEngine;
@@ -348,7 +349,9 @@ namespace Umbraco.Web
{
base.InitializeResolvers();
- XsltExtensionsResolver.Current = new XsltExtensionsResolver(ServiceProvider, LoggerResolver.Current.Logger, () => PluginManager.Current.ResolveXsltExtensions());
+ XsltExtensionsResolver.Current = new XsltExtensionsResolver(ServiceProvider, LoggerResolver.Current.Logger, () => PluginManager.ResolveXsltExtensions());
+
+ EditorValidationResolver.Current= new EditorValidationResolver(ServiceProvider, LoggerResolver.Current.Logger, () => PluginManager.ResolveTypes());
//set the default RenderMvcController
DefaultRenderMvcControllerResolver.Current = new DefaultRenderMvcControllerResolver(typeof(RenderMvcController));
@@ -436,11 +439,11 @@ namespace Umbraco.Web
SurfaceControllerResolver.Current = new SurfaceControllerResolver(
ServiceProvider, LoggerResolver.Current.Logger,
- PluginManager.Current.ResolveSurfaceControllers());
+ PluginManager.ResolveSurfaceControllers());
UmbracoApiControllerResolver.Current = new UmbracoApiControllerResolver(
ServiceProvider, LoggerResolver.Current.Logger,
- PluginManager.Current.ResolveUmbracoApiControllers());
+ PluginManager.ResolveUmbracoApiControllers());
// both TinyMceValueConverter (in Core) and RteMacroRenderingValueConverter (in Web) will be
// discovered when CoreBootManager configures the converters. We HAVE to remove one of them
@@ -509,11 +512,11 @@ namespace Umbraco.Web
ThumbnailProvidersResolver.Current = new ThumbnailProvidersResolver(
ServiceProvider, LoggerResolver.Current.Logger,
- PluginManager.Current.ResolveThumbnailProviders());
+ PluginManager.ResolveThumbnailProviders());
ImageUrlProviderResolver.Current = new ImageUrlProviderResolver(
ServiceProvider, LoggerResolver.Current.Logger,
- PluginManager.Current.ResolveImageUrlProviders());
+ PluginManager.ResolveImageUrlProviders());
CultureDictionaryFactoryResolver.Current = new CultureDictionaryFactoryResolver(
new DefaultCultureDictionaryFactory());
@@ -528,3 +531,4 @@ namespace Umbraco.Web
}
}
}
+