diff --git a/src/Microsoft.AspNet.Mvc.Core/DefaultControllerFactory.cs b/src/Microsoft.AspNet.Mvc.Core/DefaultControllerFactory.cs
index 4da4083e58..926f7accb3 100644
--- a/src/Microsoft.AspNet.Mvc.Core/DefaultControllerFactory.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/DefaultControllerFactory.cs
@@ -62,6 +62,17 @@ namespace Microsoft.AspNet.Mvc
}
var controllerType = actionDescriptor.ControllerTypeInfo.AsType();
+ var controllerTypeInfo = controllerType.GetTypeInfo();
+ if (controllerTypeInfo.IsValueType ||
+ controllerTypeInfo.IsInterface ||
+ controllerTypeInfo.IsAbstract ||
+ (controllerTypeInfo.IsGenericType && controllerTypeInfo.IsGenericTypeDefinition))
+ {
+ var message = Resources.FormatValueInterfaceAbstractOrOpenGenericTypesCannotBeActivated(
+ controllerType.FullName, GetType().FullName);
+ throw new InvalidOperationException(message);
+ }
+
var controller = _controllerActivator.Create(actionContext, controllerType);
ActivateProperties(controller, actionContext);
@@ -87,13 +98,6 @@ namespace Microsoft.AspNet.Mvc
protected virtual void ActivateProperties([NotNull] object controller, [NotNull] ActionContext context)
{
var controllerType = controller.GetType();
- var controllerTypeInfo = controllerType.GetTypeInfo();
- if (controllerTypeInfo.IsValueType)
- {
- var message = Resources.FormatValueTypesCannotBeActivated(GetType().FullName);
- throw new InvalidOperationException(message);
- }
-
var propertiesToActivate = _activateActions.GetOrAdd(controllerType,
_getPropertiesToActivate);
diff --git a/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs
index d6212aa949..7b96a7681b 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs
@@ -1082,22 +1082,6 @@ namespace Microsoft.AspNet.Mvc.Core
return string.Format(CultureInfo.CurrentCulture, GetString("ActionResult_ActionReturnValueCannotBeNull"), p0);
}
- ///
- /// Value types cannot be activated by '{0}'.
- ///
- internal static string ValueTypesCannotBeActivated
- {
- get { return GetString("ValueTypesCannotBeActivated"); }
- }
-
- ///
- /// Value types cannot be activated by '{0}'.
- ///
- internal static string FormatValueTypesCannotBeActivated(object p0)
- {
- return string.Format(CultureInfo.CurrentCulture, GetString("ValueTypesCannotBeActivated"), p0);
- }
-
///
/// The type '{0}' must derive from '{1}'.
///
@@ -1786,6 +1770,22 @@ namespace Microsoft.AspNet.Mvc.Core
return string.Format(CultureInfo.CurrentCulture, GetString("TempData_CannotSerializeDictionary"), p0, p1);
}
+ ///
+ /// The type '{0}' cannot be activated by '{1}' because it is either a value type, an interface, an abstract class or an open generic type.
+ ///
+ internal static string ValueInterfaceAbstractOrOpenGenericTypesCannotBeActivated
+ {
+ get { return GetString("ValueInterfaceAbstractOrOpenGenericTypesCannotBeActivated"); }
+ }
+
+ ///
+ /// The type '{0}' cannot be activated by '{1}' because it is either a value type, an interface, an abstract class or an open generic type.
+ ///
+ internal static string FormatValueInterfaceAbstractOrOpenGenericTypesCannotBeActivated(object p0, object p1)
+ {
+ return string.Format(CultureInfo.CurrentCulture, GetString("ValueInterfaceAbstractOrOpenGenericTypesCannotBeActivated"), p0, p1);
+ }
+
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);
diff --git a/src/Microsoft.AspNet.Mvc.Core/Resources.resx b/src/Microsoft.AspNet.Mvc.Core/Resources.resx
index 7db062ae64..ccf380dd34 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Resources.resx
+++ b/src/Microsoft.AspNet.Mvc.Core/Resources.resx
@@ -319,9 +319,6 @@
Cannot return null from an action method with a return type of '{0}'.
-
- Value types cannot be activated by '{0}'.
-
The type '{0}' must derive from '{1}'.
@@ -460,4 +457,7 @@
The '{0}' cannot serialize a dictionary with a key of type '{1}' to session state.
+
+ The type '{0}' cannot be activated by '{1}' because it is either a value type, an interface, an abstract class or an open generic type.
+
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultControllerFactoryTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultControllerFactoryTest.cs
index 73f8cbb2b1..373b87cf70 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultControllerFactoryTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultControllerFactoryTest.cs
@@ -188,6 +188,33 @@ namespace Microsoft.AspNet.Mvc.Core
"' cannot be activated.", exception.Message);
}
+ [Theory]
+ [InlineData(typeof(int))]
+ [InlineData(typeof(OpenGenericType<>))]
+ [InlineData(typeof(AbstractType))]
+ [InlineData(typeof(InterfaceType))]
+ public void CreateController_ThrowsIfControllerCannotBeActivated(Type type)
+ {
+ // Arrange
+ var actionDescriptor = new ControllerActionDescriptor
+ {
+ ControllerTypeInfo = type.GetTypeInfo()
+ };
+ var services = GetServices();
+ var httpContext = new DefaultHttpContext
+ {
+ RequestServices = services
+ };
+ var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
+ var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));
+
+ // Act and Assert
+ var exception = Assert.Throws(() => factory.CreateController(context));
+ Assert.Equal("The type '" + type.FullName + "' cannot be activated by '" + typeof(DefaultControllerFactory) +
+ "' because it is either a value type, an interface, an abstract class or an open generic type.",
+ exception.Message);
+ }
+
[Fact]
public void DefaultControllerFactory_DisposesIDisposableController()
{
@@ -290,5 +317,20 @@ namespace Microsoft.AspNet.Mvc.Core
{
}
+
+ private class OpenGenericType : Controller
+ {
+
+ }
+
+ private abstract class AbstractType : Controller
+ {
+
+ }
+
+ private interface InterfaceType
+ {
+
+ }
}
}