[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 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);
|
var controller = _controllerActivator.Create(actionContext, controllerType);
|
||||||
ActivateProperties(controller, actionContext);
|
ActivateProperties(controller, actionContext);
|
||||||
|
|
||||||
|
|
@ -87,13 +98,6 @@ namespace Microsoft.AspNet.Mvc
|
||||||
protected virtual void ActivateProperties([NotNull] object controller, [NotNull] ActionContext context)
|
protected virtual void ActivateProperties([NotNull] object controller, [NotNull] ActionContext context)
|
||||||
{
|
{
|
||||||
var controllerType = controller.GetType();
|
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,
|
var propertiesToActivate = _activateActions.GetOrAdd(controllerType,
|
||||||
_getPropertiesToActivate);
|
_getPropertiesToActivate);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1082,22 +1082,6 @@ namespace Microsoft.AspNet.Mvc.Core
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("ActionResult_ActionReturnValueCannotBeNull"), p0);
|
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>
|
/// <summary>
|
||||||
/// The type '{0}' must derive from '{1}'.
|
/// The type '{0}' must derive from '{1}'.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -1786,6 +1770,22 @@ namespace Microsoft.AspNet.Mvc.Core
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("TempData_CannotSerializeDictionary"), p0, p1);
|
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)
|
private static string GetString(string name, params string[] formatterNames)
|
||||||
{
|
{
|
||||||
var value = _resourceManager.GetString(name);
|
var value = _resourceManager.GetString(name);
|
||||||
|
|
|
||||||
|
|
@ -319,9 +319,6 @@
|
||||||
<data name="ActionResult_ActionReturnValueCannotBeNull" xml:space="preserve">
|
<data name="ActionResult_ActionReturnValueCannotBeNull" xml:space="preserve">
|
||||||
<value>Cannot return null from an action method with a return type of '{0}'.</value>
|
<value>Cannot return null from an action method with a return type of '{0}'.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ValueTypesCannotBeActivated" xml:space="preserve">
|
|
||||||
<value>Value types cannot be activated by '{0}'.</value>
|
|
||||||
</data>
|
|
||||||
<data name="TypeMustDeriveFromType" xml:space="preserve">
|
<data name="TypeMustDeriveFromType" xml:space="preserve">
|
||||||
<value>The type '{0}' must derive from '{1}'.</value>
|
<value>The type '{0}' must derive from '{1}'.</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
@ -460,4 +457,7 @@
|
||||||
<data name="TempData_CannotSerializeDictionary" xml:space="preserve">
|
<data name="TempData_CannotSerializeDictionary" xml:space="preserve">
|
||||||
<value>The '{0}' cannot serialize a dictionary with a key of type '{1}' to session state.</value>
|
<value>The '{0}' cannot serialize a dictionary with a key of type '{1}' to session state.</value>
|
||||||
</data>
|
</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>
|
</root>
|
||||||
|
|
@ -188,6 +188,33 @@ namespace Microsoft.AspNet.Mvc.Core
|
||||||
"' cannot be activated.", exception.Message);
|
"' 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]
|
[Fact]
|
||||||
public void DefaultControllerFactory_DisposesIDisposableController()
|
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