[Fixes #662] Throw if controller cannot be activated

This commit is contained in:
Ajay Bhargav Baaskaran 2015-04-21 16:17:45 -07:00
parent 4df7d52210
commit 1511ea34a8
4 changed files with 72 additions and 26 deletions

View File

@ -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);

View File

@ -1082,22 +1082,6 @@ namespace Microsoft.AspNet.Mvc.Core
return string.Format(CultureInfo.CurrentCulture, GetString("ActionResult_ActionReturnValueCannotBeNull"), p0);
}
/// <summary>
/// Value types cannot be activated by '{0}'.
/// </summary>
internal static string ValueTypesCannotBeActivated
{
get { return GetString("ValueTypesCannotBeActivated"); }
}
/// <summary>
/// Value types cannot be activated by '{0}'.
/// </summary>
internal static string FormatValueTypesCannotBeActivated(object p0)
{
return string.Format(CultureInfo.CurrentCulture, GetString("ValueTypesCannotBeActivated"), p0);
}
/// <summary>
/// The type '{0}' must derive from '{1}'.
/// </summary>
@ -1786,6 +1770,22 @@ namespace Microsoft.AspNet.Mvc.Core
return string.Format(CultureInfo.CurrentCulture, GetString("TempData_CannotSerializeDictionary"), p0, p1);
}
/// <summary>
/// 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.
/// </summary>
internal static string ValueInterfaceAbstractOrOpenGenericTypesCannotBeActivated
{
get { return GetString("ValueInterfaceAbstractOrOpenGenericTypesCannotBeActivated"); }
}
/// <summary>
/// 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.
/// </summary>
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);

View File

@ -319,9 +319,6 @@
<data name="ActionResult_ActionReturnValueCannotBeNull" xml:space="preserve">
<value>Cannot return null from an action method with a return type of '{0}'.</value>
</data>
<data name="ValueTypesCannotBeActivated" xml:space="preserve">
<value>Value types cannot be activated by '{0}'.</value>
</data>
<data name="TypeMustDeriveFromType" xml:space="preserve">
<value>The type '{0}' must derive from '{1}'.</value>
</data>
@ -460,4 +457,7 @@
<data name="TempData_CannotSerializeDictionary" xml:space="preserve">
<value>The '{0}' cannot serialize a dictionary with a key of type '{1}' to session state.</value>
</data>
<data name="ValueInterfaceAbstractOrOpenGenericTypesCannotBeActivated" xml:space="preserve">
<value>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.</value>
</data>
</root>

View File

@ -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<InvalidOperationException>(() => 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<T> : Controller
{
}
private abstract class AbstractType : Controller
{
}
private interface InterfaceType
{
}
}
}