* Modify DefaultControllerTypeProvider to look at the object graph to
determine if any ancestor has the "Controller" suffix. * Introduce NonControllerAttribute to opt out of Controller detection. Fixes #1274
This commit is contained in:
parent
8a9d0d16f7
commit
5e69d90076
32
Mvc.sln
32
Mvc.sln
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.22606.0
|
||||
VisualStudioVersion = 14.0.22604.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{DAAE4C74-D06F-4874-A166-33305D2643CE}"
|
||||
EndProject
|
||||
|
|
@ -140,6 +140,10 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "RazorCompilerCacheWebSite",
|
|||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.PageExecutionInstrumentation", "src\Microsoft.AspNet.PageExecutionInstrumentation\Microsoft.AspNet.PageExecutionInstrumentation.kproj", "{4DA2D7C1-A7B6-4C01-B57D-89E6EA4609DE}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "UserClassLibrary", "test\WebSites\UserClassLibrary\UserClassLibrary.kproj", "{C651F432-4EBE-41A6-BAD2-3E07CCBA209C}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ControllerDiscoveryConventionsWebSite", "test\WebSites\ControllerDiscoveryConventionsWebSite\ControllerDiscoveryConventionsWebSite.kproj", "{A19022EF-9BA3-4349-94E4-F48E13E1C8AE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -810,6 +814,30 @@ Global
|
|||
{4DA2D7C1-A7B6-4C01-B57D-89E6EA4609DE}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{4DA2D7C1-A7B6-4C01-B57D-89E6EA4609DE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4DA2D7C1-A7B6-4C01-B57D-89E6EA4609DE}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C651F432-4EBE-41A6-BAD2-3E07CCBA209C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C651F432-4EBE-41A6-BAD2-3E07CCBA209C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C651F432-4EBE-41A6-BAD2-3E07CCBA209C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{C651F432-4EBE-41A6-BAD2-3E07CCBA209C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{C651F432-4EBE-41A6-BAD2-3E07CCBA209C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C651F432-4EBE-41A6-BAD2-3E07CCBA209C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C651F432-4EBE-41A6-BAD2-3E07CCBA209C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C651F432-4EBE-41A6-BAD2-3E07CCBA209C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C651F432-4EBE-41A6-BAD2-3E07CCBA209C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{C651F432-4EBE-41A6-BAD2-3E07CCBA209C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{C651F432-4EBE-41A6-BAD2-3E07CCBA209C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C651F432-4EBE-41A6-BAD2-3E07CCBA209C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{A19022EF-9BA3-4349-94E4-F48E13E1C8AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A19022EF-9BA3-4349-94E4-F48E13E1C8AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A19022EF-9BA3-4349-94E4-F48E13E1C8AE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{A19022EF-9BA3-4349-94E4-F48E13E1C8AE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{A19022EF-9BA3-4349-94E4-F48E13E1C8AE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{A19022EF-9BA3-4349-94E4-F48E13E1C8AE}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{A19022EF-9BA3-4349-94E4-F48E13E1C8AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A19022EF-9BA3-4349-94E4-F48E13E1C8AE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A19022EF-9BA3-4349-94E4-F48E13E1C8AE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{A19022EF-9BA3-4349-94E4-F48E13E1C8AE}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{A19022EF-9BA3-4349-94E4-F48E13E1C8AE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{A19022EF-9BA3-4349-94E4-F48E13E1C8AE}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -878,5 +906,7 @@ Global
|
|||
{551DC89E-2A13-4CF2-83D7-1ADD802443D5} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
{42C5D417-4060-48F4-BB28-E9E179007779} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
{4DA2D7C1-A7B6-4C01-B57D-89E6EA4609DE} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
|
||||
{C651F432-4EBE-41A6-BAD2-3E07CCBA209C} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
{A19022EF-9BA3-4349-94E4-F48E13E1C8AE} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq.Expressions;
|
||||
using System.Security.Principal;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
|
@ -12,16 +12,21 @@ using Microsoft.AspNet.Mvc.Core;
|
|||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.Mvc.Rendering;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public class Controller : IActionFilter, IAsyncActionFilter, IDisposable
|
||||
/// <summary>
|
||||
/// Base class for an MVC controller.
|
||||
/// </summary>
|
||||
public abstract class Controller : IActionFilter, IAsyncActionFilter, IDisposable
|
||||
{
|
||||
private DynamicViewData _viewBag;
|
||||
private ViewDataDictionary _viewData;
|
||||
private ActionContext _actionContext;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the request-specific <see cref="IServiceProvider"/>.
|
||||
/// </summary>
|
||||
public IServiceProvider Resolver
|
||||
{
|
||||
get
|
||||
|
|
@ -30,6 +35,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="HttpContext"/> for the executing action.
|
||||
/// </summary>
|
||||
public HttpContext Context
|
||||
{
|
||||
get
|
||||
|
|
@ -38,6 +46,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="HttpRequest"/> for the executing action.
|
||||
/// </summary>
|
||||
public HttpRequest Request
|
||||
{
|
||||
get
|
||||
|
|
@ -46,6 +57,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="HttpResponse"/> for the executing action.
|
||||
/// </summary>
|
||||
public HttpResponse Response
|
||||
{
|
||||
get
|
||||
|
|
@ -54,14 +68,20 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="AspNet.Routing.RouteData"/> for the executing action.
|
||||
/// </summary>
|
||||
public RouteData RouteData
|
||||
{
|
||||
get
|
||||
{
|
||||
return ActionContext?.RouteData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ModelStateDictionary"/> that contains the state of the model and of model-binding validation.
|
||||
/// </summary>
|
||||
public ModelStateDictionary ModelState
|
||||
{
|
||||
get
|
||||
|
|
@ -97,16 +117,28 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="ActionBindingContext"/>.
|
||||
/// </summary>
|
||||
[Activate]
|
||||
public ActionBindingContext BindingContext { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="IModelMetadataProvider"/>.
|
||||
/// </summary>
|
||||
[FromServices]
|
||||
public IModelMetadataProvider MetadataProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="IUrlHelper"/>.
|
||||
/// </summary>
|
||||
[FromServices]
|
||||
public IUrlHelper Url { get; set; }
|
||||
|
||||
public IPrincipal User
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="ClaimsPrincipal"/> for user associated with the executing action.
|
||||
/// </summary>
|
||||
public ClaimsPrincipal User
|
||||
{
|
||||
get
|
||||
{
|
||||
|
|
@ -138,7 +170,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
return _viewData;
|
||||
}
|
||||
set
|
||||
{
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw
|
||||
|
|
@ -149,6 +181,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the dynamic view bag.
|
||||
/// </summary>
|
||||
public dynamic ViewBag
|
||||
{
|
||||
get
|
||||
|
|
@ -1111,12 +1146,18 @@ namespace Microsoft.AspNet.Mvc
|
|||
return ModelState.IsValid;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases all resources currently used by this <see cref="Controller"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="disposing"><c>true</c> if this method is being invoked by the <see cref="Dispose"/> method,
|
||||
/// otherwise <c>false</c>.</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,10 +12,21 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
public class DefaultAssemblyProvider : IAssemblyProvider
|
||||
{
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
||||
public DefaultAssemblyProvider(ILibraryManager libraryManager)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the set of assembly names that are used as root for discovery of
|
||||
/// MVC controllers, view components and views.
|
||||
/// </summary>
|
||||
// DefaultControllerTypeProvider uses CandidateAssemblies to determine if the base type of a POCO controller
|
||||
// lives in an assembly that references MVC. CandidateAssemblies excludes all assemblies from the
|
||||
// ReferenceAssemblies set. Consequently adding WebApiCompatShim to this set would cause the ApiController to
|
||||
/// fail this test.
|
||||
protected virtual HashSet<string> ReferenceAssemblies { get; } = new HashSet<string>(StringComparer.Ordinal)
|
||||
{
|
||||
"Microsoft.AspNet.Mvc",
|
||||
|
|
@ -23,16 +34,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
"Microsoft.AspNet.Mvc.ModelBinding",
|
||||
"Microsoft.AspNet.Mvc.Razor",
|
||||
"Microsoft.AspNet.Mvc.Razor.Host",
|
||||
"Microsoft.AspNet.Mvc.Rendering",
|
||||
};
|
||||
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
||||
public DefaultAssemblyProvider(ILibraryManager libraryManager)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<Assembly> CandidateAssemblies
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// </summary>
|
||||
public class DefaultControllerTypeProvider : IControllerTypeProvider
|
||||
{
|
||||
private const string ControllerTypeName = nameof(Controller);
|
||||
private static readonly TypeInfo ControllerTypeInfo = typeof(Controller).GetTypeInfo();
|
||||
private static readonly TypeInfo ObjectTypeInfo = typeof(object).GetTypeInfo();
|
||||
private readonly IAssemblyProvider _assemblyProvider;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
|
|
@ -37,17 +40,17 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
get
|
||||
{
|
||||
var assemblies = _assemblyProvider.CandidateAssemblies;
|
||||
var candidateAssemblies = new HashSet<Assembly>(_assemblyProvider.CandidateAssemblies);
|
||||
if (_logger.IsEnabled(LogLevel.Verbose))
|
||||
{
|
||||
foreach (var assembly in assemblies)
|
||||
foreach (var assembly in candidateAssemblies)
|
||||
{
|
||||
_logger.WriteVerbose(new AssemblyValues(assembly));
|
||||
}
|
||||
}
|
||||
|
||||
var types = assemblies.SelectMany(a => a.DefinedTypes);
|
||||
return types.Where(IsController);
|
||||
var types = candidateAssemblies.SelectMany(a => a.DefinedTypes);
|
||||
return types.Where(typeInfo => IsController(typeInfo, candidateAssemblies));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -55,8 +58,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// Returns <c>true</c> if the <paramref name="typeInfo"/> is a controller. Otherwise <c>false</c>.
|
||||
/// </summary>
|
||||
/// <param name="typeInfo">The <see cref="TypeInfo"/>.</param>
|
||||
/// <param name="candidateAssemblies">The set of candidate assemblies.</param>
|
||||
/// <returns><c>true</c> if the <paramref name="typeInfo"/> is a controller. Otherwise <c>false</c>.</returns>
|
||||
protected internal virtual bool IsController([NotNull] TypeInfo typeInfo)
|
||||
protected internal virtual bool IsController([NotNull] TypeInfo typeInfo,
|
||||
[NotNull] ISet<Assembly> candidateAssemblies)
|
||||
{
|
||||
if (!typeInfo.IsClass)
|
||||
{
|
||||
|
|
@ -76,17 +81,47 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
return false;
|
||||
}
|
||||
if (typeInfo.Name.Equals("Controller", StringComparison.OrdinalIgnoreCase))
|
||||
if (!typeInfo.Name.EndsWith(ControllerTypeName, StringComparison.OrdinalIgnoreCase) &&
|
||||
!DerivesFromController(typeInfo, candidateAssemblies))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!typeInfo.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) &&
|
||||
!typeof(Controller).GetTypeInfo().IsAssignableFrom(typeInfo))
|
||||
if (typeInfo.IsDefined(typeof(NonControllerAttribute)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool DerivesFromController(TypeInfo typeInfo, ISet<Assembly> candidateAssemblies)
|
||||
{
|
||||
// A type is a controller if it derives from a type that is either named "Controller" or has the suffix
|
||||
// "Controller". We'll optimize the most common case of types deriving from the Mvc Controller type and
|
||||
// walk up the object graph if that's not the case.
|
||||
if (ControllerTypeInfo.IsAssignableFrom(typeInfo))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
while (typeInfo != ObjectTypeInfo)
|
||||
{
|
||||
var baseTypeInfo = typeInfo.BaseType.GetTypeInfo();
|
||||
|
||||
// A base type will be treated as a controller if
|
||||
// a) it ends in the term "Controller" and
|
||||
// b) it's assembly is one of the candidate assemblies we're considering. This ensures that the assembly
|
||||
// the base type is declared in references Mvc.
|
||||
if (baseTypeInfo.Name.EndsWith(ControllerTypeName, StringComparison.Ordinal) &&
|
||||
candidateAssemblies.Contains(baseTypeInfo.Assembly))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
typeInfo = baseTypeInfo;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that the type and any derived types that this attribute is applied to
|
||||
/// is not considered a controller by the default controller discovery mechanism.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
|
||||
public sealed class NonControllerAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -40,7 +40,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
{
|
||||
// Arrange
|
||||
var metadataProvider = new DataAnnotationsModelMetadataProvider();
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var originalViewData = controller.ViewData = new ViewDataDictionary<object>(metadataProvider);
|
||||
var replacementViewData = new ViewDataDictionary<object>(metadataProvider);
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void Redirect_WithParameterUrl_SetsRedirectResultSameUrl()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var url = "/test/url";
|
||||
|
||||
// Act
|
||||
|
|
@ -77,7 +77,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void RedirectPermanent_WithParameterUrl_SetsRedirectResultPermanentAndSameUrl()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var url = "/test/url";
|
||||
|
||||
// Act
|
||||
|
|
@ -95,7 +95,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void Redirect_WithParameter_NullOrEmptyUrl_Throws(string url)
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act & Assert
|
||||
ExceptionAssert.ThrowsArgumentNullOrEmpty(
|
||||
|
|
@ -108,7 +108,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void RedirectPermanent_WithParameter_NullOrEmptyUrl_Throws(string url)
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act & Assert
|
||||
ExceptionAssert.ThrowsArgumentNullOrEmpty(
|
||||
|
|
@ -119,7 +119,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void RedirectToAction_WithParameterActionName_SetsResultActionName()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act
|
||||
var resultTemporary = controller.RedirectToAction("SampleAction");
|
||||
|
|
@ -134,7 +134,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void RedirectToActionPermanent_WithParameterActionName_SetsResultActionNameAndPermanent()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act
|
||||
var resultPermanent = controller.RedirectToActionPermanent("SampleAction");
|
||||
|
|
@ -152,7 +152,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void RedirectToAction_WithParameterActionAndControllerName_SetsEqualNames(string controllerName)
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act
|
||||
var resultTemporary = controller.RedirectToAction("SampleAction", controllerName);
|
||||
|
|
@ -172,7 +172,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
string controllerName)
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act
|
||||
var resultPermanent = controller.RedirectToActionPermanent("SampleAction", controllerName);
|
||||
|
|
@ -191,7 +191,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
IEnumerable<KeyValuePair<string, object>> expected)
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act
|
||||
var resultTemporary = controller.RedirectToAction("SampleAction", "SampleController", routeValues);
|
||||
|
|
@ -211,7 +211,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
IEnumerable<KeyValuePair<string, object>> expected)
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act
|
||||
var resultPermanent = controller.RedirectToActionPermanent(
|
||||
|
|
@ -234,7 +234,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
IEnumerable<KeyValuePair<string, object>> expected)
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act
|
||||
var resultTemporary = controller.RedirectToAction(actionName: null, routeValues: routeValues);
|
||||
|
|
@ -253,7 +253,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
IEnumerable<KeyValuePair<string, object>> expected)
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act
|
||||
var resultPermanent = controller.RedirectToActionPermanent(null, routeValues);
|
||||
|
|
@ -272,7 +272,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
IEnumerable<KeyValuePair<string, object>> expected)
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act
|
||||
var resultTemporary = controller.RedirectToRoute(routeValues);
|
||||
|
|
@ -290,7 +290,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
IEnumerable<KeyValuePair<string, object>> expected)
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act
|
||||
var resultPermanent = controller.RedirectToRoutePermanent(routeValues);
|
||||
|
|
@ -305,7 +305,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void RedirectToRoute_WithParameterRouteName_SetsResultSameRouteName()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var routeName = "CustomRouteName";
|
||||
|
||||
// Act
|
||||
|
|
@ -321,7 +321,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void RedirectToRoutePermanent_WithParameterRouteName_SetsResultSameRouteNameAndPermanent()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var routeName = "CustomRouteName";
|
||||
|
||||
// Act
|
||||
|
|
@ -340,7 +340,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
IEnumerable<KeyValuePair<string, object>> expected)
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var routeName = "CustomRouteName";
|
||||
|
||||
// Act
|
||||
|
|
@ -360,7 +360,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
IEnumerable<KeyValuePair<string, object>> expected)
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var routeName = "CustomRouteName";
|
||||
|
||||
// Act
|
||||
|
|
@ -377,7 +377,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void Created_WithStringParameter_SetsCreatedLocation()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var uri = "http://test/url";
|
||||
|
||||
// Act
|
||||
|
|
@ -393,7 +393,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void Created_WithAbsoluteUriParameter_SetsCreatedLocation()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var uri = new Uri("http://test/url");
|
||||
|
||||
// Act
|
||||
|
|
@ -409,7 +409,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void Created_WithRelativeUriParameter_SetsCreatedLocation()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var uri = new Uri("/test/url", UriKind.Relative);
|
||||
|
||||
// Act
|
||||
|
|
@ -425,7 +425,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void CreatedAtAction_WithParameterActionName_SetsResultActionName()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act
|
||||
var result = controller.CreatedAtAction("SampleAction", null);
|
||||
|
|
@ -444,7 +444,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
string controllerName)
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act
|
||||
var result = controller.CreatedAtAction("SampleAction", controllerName, null, null);
|
||||
|
|
@ -460,7 +460,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void CreatedAtAction_WithActionControllerRouteValues_SetsSameValues()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var expected = new Dictionary<string, object>
|
||||
{
|
||||
{ "test", "case" },
|
||||
|
|
@ -485,7 +485,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void CreatedAtRoute_WithParameterRouteName_SetsResultSameRouteName()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var routeName = "SampleRoute";
|
||||
|
||||
// Act
|
||||
|
|
@ -500,7 +500,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void CreatedAtRoute_WithParameterRouteValues_SetsResultSameRouteValues()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var expected = new Dictionary<string, object>
|
||||
{
|
||||
{ "test", "case" },
|
||||
|
|
@ -520,7 +520,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void CreatedAtRoute_WithParameterRouteNameAndValues_SetsResultSameProperties()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var routeName = "SampleRoute";
|
||||
var expected = new Dictionary<string, object>
|
||||
{
|
||||
|
|
@ -542,7 +542,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void File_WithContents()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var fileContents = new byte[0];
|
||||
|
||||
// Act
|
||||
|
|
@ -559,7 +559,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void File_WithContentsAndFileDownloadName()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var fileContents = new byte[0];
|
||||
|
||||
// Act
|
||||
|
|
@ -576,7 +576,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void File_WithPath()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var path = Path.GetFullPath("somepath");
|
||||
|
||||
// Act
|
||||
|
|
@ -593,7 +593,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void File_WithPathAndFileDownloadName()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var path = Path.GetFullPath("somepath");
|
||||
|
||||
// Act
|
||||
|
|
@ -610,7 +610,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void File_WithStream()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var fileStream = Stream.Null;
|
||||
|
||||
// Act
|
||||
|
|
@ -627,7 +627,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void File_WithStreamAndFileDownloadName()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var fileStream = Stream.Null;
|
||||
|
||||
// Act
|
||||
|
|
@ -645,7 +645,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void HttpNotFound_SetsStatusCode()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act
|
||||
var result = controller.HttpNotFound();
|
||||
|
|
@ -659,7 +659,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void BadRequest_SetsStatusCode()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act
|
||||
var result = controller.HttpBadRequest();
|
||||
|
|
@ -673,7 +673,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void BadRequest_SetsStatusCodeAndValue_Object()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var obj = new object();
|
||||
|
||||
// Act
|
||||
|
|
@ -689,7 +689,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void BadRequest_SetsStatusCodeAndValue_ModelState()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act
|
||||
var result = controller.HttpBadRequest(new ModelStateDictionary());
|
||||
|
|
@ -713,7 +713,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void Controller_View_WithoutParameter_SetsResultNullViewNameAndNullViewDataModel()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller()
|
||||
var controller = new TestableController()
|
||||
{
|
||||
ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()),
|
||||
};
|
||||
|
|
@ -732,7 +732,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void Controller_View_WithParameterViewName_SetsResultViewNameAndNullViewDataModel()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller()
|
||||
var controller = new TestableController()
|
||||
{
|
||||
ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()),
|
||||
};
|
||||
|
|
@ -751,7 +751,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void Controller_View_WithParameterViewModel_SetsResultNullViewNameAndViewDataModel()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller()
|
||||
var controller = new TestableController()
|
||||
{
|
||||
ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()),
|
||||
};
|
||||
|
|
@ -771,7 +771,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void Controller_View_WithParameterViewNameAndViewModel_SetsResultViewNameAndViewDataModel()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller()
|
||||
var controller = new TestableController()
|
||||
{
|
||||
ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()),
|
||||
};
|
||||
|
|
@ -791,7 +791,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void Controller_Content_WithParameterContentString_SetsResultContent()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act
|
||||
var actualContentResult = controller.Content("TestContent");
|
||||
|
|
@ -807,7 +807,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void Controller_Content_WithParameterContentStringAndContentType_SetsResultContentAndContentType()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act
|
||||
var actualContentResult = controller.Content("TestContent", "text/plain");
|
||||
|
|
@ -823,7 +823,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void Controller_Content_WithParameterContentAndTypeAndEncoding_SetsResultContentAndTypeAndEncoding()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
// Act
|
||||
var actualContentResult = controller.Content("TestContent", "text/plain", Encoding.UTF8);
|
||||
|
|
@ -839,7 +839,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void Controller_Json_WithParameterValue_SetsResultData()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var data = new object();
|
||||
|
||||
// Act
|
||||
|
|
@ -1144,7 +1144,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void ControllerExposes_RequestServices()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
var serviceProvider = Mock.Of<IServiceProvider>();
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
|
|
@ -1166,7 +1166,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void ControllerExposes_Request()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
var request = Mock.Of<HttpRequest>();
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
|
|
@ -1188,7 +1188,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void ControllerExposes_Response()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
var response = Mock.Of<HttpResponse>();
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
|
|
@ -1210,7 +1210,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void ControllerExposes_RouteData()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
|
||||
var routeData = Mock.Of<RouteData>();
|
||||
|
||||
|
|
@ -1325,7 +1325,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void TryValidateModelEmptyBindingContextThrowsException()
|
||||
{
|
||||
// Arrange
|
||||
var controller = new Controller();
|
||||
var controller = new TestableController();
|
||||
var model = new TryValidateModelModel();
|
||||
|
||||
// Act & Assert
|
||||
|
|
@ -1346,7 +1346,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
ValueProvider = provider,
|
||||
};
|
||||
|
||||
return new Controller()
|
||||
return new TestableController()
|
||||
{
|
||||
ActionContext = actionContext,
|
||||
BindingContext = bindingContext,
|
||||
|
|
@ -1397,5 +1397,10 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
DisposeCalled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private class TestableController : Controller
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -490,8 +490,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// Arrange
|
||||
var actionContext = new ActionContext();
|
||||
var controller1 = new Controller();
|
||||
var controller2 = new Controller();
|
||||
var controller1 = new TestabilityController();
|
||||
var controller2 = new TestabilityController();
|
||||
|
||||
// Act
|
||||
controller2.ActionContext = actionContext;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNet.Mvc.DefaultControllerTypeProviderControllers;
|
||||
using Xunit;
|
||||
|
|
@ -10,6 +11,11 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
public class DefaultControllerTypeProviderTest
|
||||
{
|
||||
private static readonly ISet<Assembly> CandidateAssemblies = new HashSet<Assembly>
|
||||
{
|
||||
typeof(StoreController).GetTypeInfo().Assembly
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void IsController_UserDefinedClass()
|
||||
{
|
||||
|
|
@ -18,7 +24,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
var provider = GetControllerTypeProvider();
|
||||
|
||||
// Act
|
||||
var isController = provider.IsController(typeInfo);
|
||||
var isController = provider.IsController(typeInfo, CandidateAssemblies);
|
||||
|
||||
// Assert
|
||||
Assert.True(isController);
|
||||
|
|
@ -32,7 +38,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
var provider = GetControllerTypeProvider();
|
||||
|
||||
// Act
|
||||
var isController = provider.IsController(typeInfo);
|
||||
var isController = provider.IsController(typeInfo, CandidateAssemblies);
|
||||
|
||||
// Assert
|
||||
Assert.False(isController);
|
||||
|
|
@ -46,7 +52,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
var provider = GetControllerTypeProvider();
|
||||
|
||||
// Act
|
||||
var isController = provider.IsController(typeInfo);
|
||||
var isController = provider.IsController(typeInfo, CandidateAssemblies);
|
||||
|
||||
// Assert
|
||||
Assert.False(isController);
|
||||
|
|
@ -60,7 +66,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
var provider = GetControllerTypeProvider();
|
||||
|
||||
// Act
|
||||
var isController = provider.IsController(typeInfo);
|
||||
var isController = provider.IsController(typeInfo, CandidateAssemblies);
|
||||
|
||||
// Assert
|
||||
Assert.False(isController);
|
||||
|
|
@ -74,7 +80,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
var provider = GetControllerTypeProvider();
|
||||
|
||||
// Act
|
||||
var isController = provider.IsController(typeInfo);
|
||||
var isController = provider.IsController(typeInfo, CandidateAssemblies);
|
||||
|
||||
// Assert
|
||||
Assert.False(isController);
|
||||
|
|
@ -88,7 +94,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
var provider = GetControllerTypeProvider();
|
||||
|
||||
// Act
|
||||
var isController = provider.IsController(typeInfo);
|
||||
var isController = provider.IsController(typeInfo, CandidateAssemblies);
|
||||
|
||||
// Assert
|
||||
Assert.True(isController);
|
||||
|
|
@ -102,7 +108,21 @@ namespace Microsoft.AspNet.Mvc
|
|||
var provider = GetControllerTypeProvider();
|
||||
|
||||
// Act
|
||||
var isController = provider.IsController(typeInfo);
|
||||
var isController = provider.IsController(typeInfo, CandidateAssemblies);
|
||||
|
||||
// Assert
|
||||
Assert.False(isController);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsController_WithoutSuffixOrAncestorWithController()
|
||||
{
|
||||
// Arrange
|
||||
var typeInfo = typeof(NoSuffixPoco).GetTypeInfo();
|
||||
var provider = GetControllerTypeProvider();
|
||||
|
||||
// Act
|
||||
var isController = provider.IsController(typeInfo, CandidateAssemblies);
|
||||
|
||||
// Assert
|
||||
Assert.False(isController);
|
||||
|
|
@ -116,7 +136,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
var provider = GetControllerTypeProvider();
|
||||
|
||||
// Act
|
||||
var isController = provider.IsController(typeInfo);
|
||||
var isController = provider.IsController(typeInfo, CandidateAssemblies);
|
||||
|
||||
// Assert
|
||||
Assert.True(isController);
|
||||
|
|
@ -130,7 +150,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
var provider = GetControllerTypeProvider();
|
||||
|
||||
// Act
|
||||
var isController = provider.IsController(typeInfo);
|
||||
var isController = provider.IsController(typeInfo, CandidateAssemblies);
|
||||
|
||||
// Assert
|
||||
Assert.True(isController);
|
||||
|
|
@ -144,7 +164,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
var provider = GetControllerTypeProvider();
|
||||
|
||||
// Act
|
||||
var isController = provider.IsController(typeInfo);
|
||||
var isController = provider.IsController(typeInfo, CandidateAssemblies);
|
||||
|
||||
// Assert
|
||||
Assert.True(isController);
|
||||
|
|
@ -158,12 +178,47 @@ namespace Microsoft.AspNet.Mvc
|
|||
var provider = GetControllerTypeProvider();
|
||||
|
||||
// Act
|
||||
var isController = provider.IsController(typeInfo);
|
||||
var isController = provider.IsController(typeInfo, CandidateAssemblies);
|
||||
|
||||
// Assert
|
||||
Assert.True(isController);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(typeof(DescendantLevel1))]
|
||||
[InlineData(typeof(DescendantLevel2))]
|
||||
public void IsController_ReturnsTrue_IfAncestorTypeNameHasControllerSuffix(Type type)
|
||||
{
|
||||
// Arrange
|
||||
var provider = GetControllerTypeProvider();
|
||||
|
||||
// Act
|
||||
var isController = provider.IsController(type.GetTypeInfo(), CandidateAssemblies);
|
||||
|
||||
// Assert
|
||||
Assert.True(isController);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(typeof(BaseNonControllerController))]
|
||||
[InlineData(typeof(BaseNonControllerControllerChild))]
|
||||
[InlineData(typeof(BasePocoNonControllerController))]
|
||||
[InlineData(typeof(BasePocoNonControllerControllerChild))]
|
||||
[InlineData(typeof(NonController))]
|
||||
[InlineData(typeof(NonControllerChild))]
|
||||
[InlineData(typeof(PersonModel))] // Verifies that POCO type hierarchies that don't derive from controller return false.
|
||||
public void IsController_ReturnsFalse_IfTypeOrAncestorHasNonControllerAttribute(Type type)
|
||||
{
|
||||
// Arrange
|
||||
var provider = GetControllerTypeProvider();
|
||||
|
||||
// Act
|
||||
var isController = provider.IsController(type.GetTypeInfo(), CandidateAssemblies);
|
||||
|
||||
// Assert
|
||||
Assert.False(isController);
|
||||
}
|
||||
|
||||
private static DefaultControllerTypeProvider GetControllerTypeProvider()
|
||||
{
|
||||
var assemblyProvider = new FixedSetAssemblyProvider();
|
||||
|
|
@ -191,7 +246,7 @@ namespace Microsoft.AspNet.Mvc.DefaultControllerTypeProviderControllers
|
|||
{
|
||||
}
|
||||
|
||||
public class Controller
|
||||
public abstract class Controller
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +266,86 @@ namespace Microsoft.AspNet.Mvc.DefaultControllerTypeProviderControllers
|
|||
{
|
||||
}
|
||||
|
||||
public class NoSuffixPoco
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class PocoController
|
||||
{
|
||||
}
|
||||
|
||||
public class CustomBaseController
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public abstract class CustomAbstractBaseController
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class DescendantLevel1 : CustomBaseController
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class DescendantLevel2 : DescendantLevel1
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class AbstractChildWithoutSuffix : CustomAbstractBaseController
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[NonController]
|
||||
public class BasePocoNonControllerController
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class BasePocoNonControllerControllerChild : BasePocoNonControllerController
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[NonController]
|
||||
public class BaseNonControllerController : Controller
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class BaseNonControllerControllerChild : BaseNonControllerController
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[NonController]
|
||||
public class NonControllerChild : Controller
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[NonController]
|
||||
public class NonController : Controller
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class DataModelBase
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class EntityDataModel : DataModelBase
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class PersonModel : EntityDataModel
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
|
|
@ -18,7 +19,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
{
|
||||
public class BasicTests
|
||||
{
|
||||
private readonly IServiceProvider _provider = TestHelper.CreateServices("BasicWebSite");
|
||||
private readonly IServiceProvider _provider = TestHelper.CreateServices(nameof(BasicWebSite));
|
||||
private readonly Action<IApplicationBuilder> _app = new Startup().Configure;
|
||||
|
||||
// Some tests require comparing the actual response body against an expected response baseline
|
||||
|
|
@ -275,5 +276,33 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var responseData = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("This is a basic website.", responseData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TypesWithoutControllerSuffix_DerivingFromTypesWithControllerSuffix_CanBeAccessed()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = new HttpClient(server.CreateHandler(), false);
|
||||
|
||||
// Act
|
||||
var response = await client.GetStringAsync("http://localhost/appointments");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("2 appointments available.", response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TypesMarkedAsNonAction_AreInaccessible()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = new HttpClient(server.CreateHandler(), false);
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/SqlData/TruncateAllDbRecords");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using ControllerDiscoveryConventionsWebSite;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Hosting;
|
||||
using Microsoft.AspNet.TestHost;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.Runtime;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||
{
|
||||
public class ControllerDiscoveryConventionTests
|
||||
{
|
||||
private readonly IServiceProvider _provider = TestHelper.CreateServices(
|
||||
nameof(ControllerDiscoveryConventionsWebSite));
|
||||
private readonly Action<IApplicationBuilder> _app = new Startup().Configure;
|
||||
|
||||
[Fact]
|
||||
public async Task AbstractControllers_AreSkipped()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
client.BaseAddress = new Uri("http://localhost/");
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("Abstract/GetValue");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TypesDerivingFromControllerBaseTypesThatDoNotReferenceMvc_AreSkipped()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
client.BaseAddress = new Uri("http://localhost/");
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("SqlTransactionManager/GetValue");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TypesMarkedWithNonController_AreSkipped()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
client.BaseAddress = new Uri("http://localhost/");
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("NonController/GetValue");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task PocoTypesWithControllerSuffix_AreDiscovered()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
client.BaseAddress = new Uri("http://localhost/");
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("Poco/GetValue");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("PocoController", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TypesDerivingFromTypesWithControllerSuffix_AreDiscovered()
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
client.BaseAddress = new Uri("http://localhost/");
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("ChildOfAbstract/GetValue");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("AbstractController", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TypesDerivingFromApiController_AreDiscovered()
|
||||
{
|
||||
// Arrange
|
||||
// TestHelper.CreateServices replaces the DefaultAssemblyProvider with a provider that
|
||||
// limits the set of candidate assemblies to the executing application. For this test,
|
||||
// we'll switch it back to using a filtered default assembly provider.
|
||||
var services = HostingServices.Create(configuration: null);
|
||||
services.AddTransient<IAssemblyProvider, FilteredDefaultAssemblyProvider>();
|
||||
var serviceProvider = TestHelper.CreateServices(nameof(ControllerDiscoveryConventionsWebSite), services);
|
||||
var server = TestServer.Create(serviceProvider, _app);
|
||||
|
||||
var client = server.CreateClient();
|
||||
client.BaseAddress = new Uri("http://localhost/");
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("PersonApi/GetValue");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Equal("PersonApi", await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
|
||||
private class FilteredDefaultAssemblyProvider : DefaultAssemblyProvider
|
||||
{
|
||||
public FilteredDefaultAssemblyProvider(ILibraryManager libraryManager)
|
||||
: base(libraryManager)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override IEnumerable<ILibraryInformation> GetCandidateLibraries()
|
||||
{
|
||||
var libraries = base.GetCandidateLibraries();
|
||||
// Filter out other WebSite projects
|
||||
return libraries.Where(library => !library.Name.Contains("WebSite") ||
|
||||
library.Name.Equals(nameof(ControllerDiscoveryConventionsWebSite), StringComparison.Ordinal));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -49,6 +49,21 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
Assert.Equal(expected, response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TypesDerivingFromControllerPrefixedTypesAreRegistered()
|
||||
{
|
||||
// Arrange
|
||||
var expected = "4";
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetStringAsync("http://localhost/inventory/");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TypesWithControllerSuffixAreRegistered()
|
||||
{
|
||||
|
|
@ -84,9 +99,10 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("generic")]
|
||||
[InlineData("nested")]
|
||||
[InlineData("not-in-services")]
|
||||
[InlineData("not-discovered/generic")]
|
||||
[InlineData("not-discovered/nested")]
|
||||
[InlineData("not-discovered/not-in-services")]
|
||||
[InlineData("ClientUIStub/GetClientContent/5")]
|
||||
public async Task AddControllersFromServices_UsesControllerDiscoveryContentions(string action)
|
||||
{
|
||||
// Arrange
|
||||
|
|
@ -94,7 +110,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var response = await client.GetAsync("http://localhost/not-discovered/" + action);
|
||||
var response = await client.GetAsync("http://localhost/" + action);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
"BasicWebSite": "1.0.0",
|
||||
"CompositeViewEngineWebSite": "1.0.0",
|
||||
"ConnegWebSite": "1.0.0",
|
||||
"ControllerDiscoveryConventionsWebSite": "1.0.0",
|
||||
"ControllersFromServicesWebSite": "1.0.0",
|
||||
"CustomRouteWebSite": "1.0.0",
|
||||
"ErrorPageMiddlewareWebSite": "1.0.0",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace BasicWebSite.Controllers
|
||||
{
|
||||
public abstract class ApplicationBaseController
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace BasicWebSite.Controllers
|
||||
{
|
||||
[Route("/appointments")]
|
||||
public class Appointments : ApplicationBaseController
|
||||
{
|
||||
[HttpGet("")]
|
||||
public IActionResult Get()
|
||||
{
|
||||
return new ContentResult
|
||||
{
|
||||
Content = "2 appointments available."
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace BasicWebSite
|
||||
{
|
||||
[NonController]
|
||||
public class SqlDataController
|
||||
{
|
||||
public int TruncateAllDbRecords()
|
||||
{
|
||||
// Return no. of tables truncated
|
||||
return 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace ControllerDiscoveryConventionsWebSite
|
||||
{
|
||||
public abstract class AbstractController
|
||||
{
|
||||
public string GetValue()
|
||||
{
|
||||
return nameof(AbstractController);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace ControllerDiscoveryConventionsWebSite
|
||||
{
|
||||
public class ChildOfAbstract : AbstractController
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="__ToolsVersion__" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>a19022ef-9ba3-4349-94e4-f48e13e1c8ae</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" Label="Configuration">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" Label="Configuration">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<DevelopmentServerPort>51163</DevelopmentServerPort>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace ControllerDiscoveryConventionsWebSite
|
||||
{
|
||||
[NonController]
|
||||
public class NonControllerController : Controller
|
||||
{
|
||||
public string GetValue()
|
||||
{
|
||||
return nameof(NonControllerController);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Web.Http;
|
||||
|
||||
namespace ControllerDiscoveryConventionsWebSite
|
||||
{
|
||||
public class PersonApi : ApiController
|
||||
{
|
||||
public string GetValue()
|
||||
{
|
||||
return nameof(PersonApi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace ControllerDiscoveryConventionsWebSite
|
||||
{
|
||||
public class PocoController
|
||||
{
|
||||
public string GetValue()
|
||||
{
|
||||
return nameof(PocoController);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace UserClassLibrary
|
||||
{
|
||||
public class SqlTransactionManager : TransactionController
|
||||
{
|
||||
public string GetValue()
|
||||
{
|
||||
return nameof(SqlTransactionManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
|
||||
namespace ControllerDiscoveryConventionsWebSite
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
var configuration = app.GetTestConfiguration();
|
||||
|
||||
app.UseServices(services =>
|
||||
{
|
||||
services.AddMvc(configuration);
|
||||
});
|
||||
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
routes.MapRoute("default", "{controller}/{action}/{id?}");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"commands": {
|
||||
"web": "Microsoft.AspNet.Hosting server=Microsoft.AspNet.Server.WebListener server.urls=http://localhost:5001",
|
||||
"kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5000"
|
||||
},
|
||||
"dependencies": {
|
||||
"UserClassLibrary": "1.0.0",
|
||||
"Kestrel": "1.0.0-*",
|
||||
"Microsoft.AspNet.Mvc": "6.0.0-*",
|
||||
"Microsoft.AspNet.Mvc.WebApiCompatShim": "6.0.0-*",
|
||||
"Microsoft.AspNet.Mvc.TestConfiguration": "1.0.0",
|
||||
"Microsoft.AspNet.Server.IIS": "1.0.0-*",
|
||||
"Microsoft.AspNet.Server.WebListener": "1.0.0-*",
|
||||
"Microsoft.AspNet.StaticFiles": "1.0.0-*"
|
||||
},
|
||||
"frameworks": {
|
||||
"aspnet50": {},
|
||||
"aspnetcore50": { }
|
||||
},
|
||||
"webroot": "wwwroot"
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
Functional test site for verifying controllers registration rules.
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace ControllersFromServicesClassLibrary
|
||||
{
|
||||
[NonController]
|
||||
public class ClientUIStubController
|
||||
{
|
||||
public object GetClientContent(int id)
|
||||
{
|
||||
return new object();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace ControllersFromServicesClassLibrary
|
||||
{
|
||||
public class Inventory : ResourcesController
|
||||
{
|
||||
[HttpGet]
|
||||
public int Get()
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace ControllersFromServicesClassLibrary
|
||||
{
|
||||
[Route("/[controller]")]
|
||||
public class ResourcesController
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace UserClassLibrary
|
||||
{
|
||||
// A type with the suffix Controller that lives in an assembly that does not reference Mvc.
|
||||
// This will not be treated as a controller in an Mvc application.
|
||||
public class TransactionController
|
||||
{
|
||||
public int UpdateTransaction()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="__ToolsVersion__" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>c651f432-4ebe-41a6-bad2-3e07ccba209c</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" Label="Configuration">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" Label="Configuration">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"frameworks": {
|
||||
"aspnet50": { },
|
||||
"aspnetcore50": {
|
||||
"dependencies": {
|
||||
"System.Runtime": "4.0.20-beta-*"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue