[Fixes #662] Throw if controller cannot be activated
This commit is contained in:
parent
4df7d52210
commit
1511ea34a8
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue