parent
7ba167fcd8
commit
b992ef0ced
2
Mvc.sln
2
Mvc.sln
|
|
@ -1,6 +1,6 @@
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.26730.10
|
VisualStudioVersion = 15.0.26831.3000
|
||||||
MinimumVisualStudioVersion = 15.0.26730.03
|
MinimumVisualStudioVersion = 15.0.26730.03
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{DAAE4C74-D06F-4874-A166-33305D2643CE}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{DAAE4C74-D06F-4874-A166-33305D2643CE}"
|
||||||
EndProject
|
EndProject
|
||||||
|
|
|
||||||
|
|
@ -166,5 +166,35 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal("/Home/CannotBeRouted", response.Headers.Location.ToString());
|
Assert.Equal("/Home/CannotBeRouted", response.Headers.Location.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("Products", "Products View")]
|
||||||
|
[InlineData("Services", "Services View")]
|
||||||
|
[InlineData("Manage", "Manage View")]
|
||||||
|
public async Task ApplicationModel_CanDuplicateController_InMultipleAreas(string areaName, string expectedContent)
|
||||||
|
{
|
||||||
|
// Arrange & Act
|
||||||
|
var response = await Client.GetAsync(areaName + "/MultipleAreas/Index");
|
||||||
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.Contains(expectedContent, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("Help", "This is the help page")]
|
||||||
|
[InlineData("MoreHelp", "This is the more help page")]
|
||||||
|
public async Task ControllerModel_CanDuplicateActions_RoutesToDifferentNames(string actionName, string expectedContent)
|
||||||
|
{
|
||||||
|
// Arrange & Act
|
||||||
|
var response = await Client.GetAsync("ActionModel/" + actionName);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
|
||||||
|
var body = await response.Content.ReadAsStringAsync();
|
||||||
|
Assert.Contains(expectedContent, body);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Manage View
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Products View
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Services View
|
||||||
|
|
@ -17,6 +17,12 @@ namespace ApplicationModelWebSite
|
||||||
return ControllerContext.ActionDescriptor.ActionName;
|
return ControllerContext.ActionDescriptor.ActionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CloneAction("MoreHelp")]
|
||||||
|
public IActionResult Help()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
private class ActionName2Attribute : Attribute, IActionModelConvention
|
private class ActionName2Attribute : Attribute, IActionModelConvention
|
||||||
{
|
{
|
||||||
private readonly string _actionName;
|
private readonly string _actionName;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
|
||||||
|
|
||||||
namespace ApplicationModelWebSite
|
namespace ApplicationModelWebSite
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace ApplicationModelWebSite.Controllers
|
||||||
|
{
|
||||||
|
[MultipleAreas("Products", "Services", "Manage")]
|
||||||
|
public class MultipleAreasController : Controller
|
||||||
|
{
|
||||||
|
public IActionResult Index()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace ApplicationModelWebSite
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
|
||||||
|
public class CloneActionAttribute : Attribute
|
||||||
|
{
|
||||||
|
public CloneActionAttribute(string newActionName)
|
||||||
|
{
|
||||||
|
ActionName = newActionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ActionName { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||||
|
|
||||||
|
namespace ApplicationModelWebSite
|
||||||
|
{
|
||||||
|
public class CloneActionConvention : IControllerModelConvention
|
||||||
|
{
|
||||||
|
public void Apply(ControllerModel controller)
|
||||||
|
{
|
||||||
|
var actionModels = new List<ActionModel>();
|
||||||
|
foreach (var action in controller.Actions)
|
||||||
|
{
|
||||||
|
var actionName = action.Attributes.OfType<CloneActionAttribute>()?.FirstOrDefault()?.ActionName;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(actionName))
|
||||||
|
{
|
||||||
|
var actionCopy = new ActionModel(action)
|
||||||
|
{
|
||||||
|
ActionName = actionName
|
||||||
|
};
|
||||||
|
|
||||||
|
actionModels.Add(actionCopy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var model in actionModels)
|
||||||
|
{
|
||||||
|
controller.Actions.Add(model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright (c) .NET Foundation. 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.Linq;
|
||||||
|
|
||||||
|
namespace ApplicationModelWebSite
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
|
||||||
|
public class MultipleAreasAttribute : Attribute
|
||||||
|
{
|
||||||
|
public MultipleAreasAttribute(string area1, string area2, params string[] areaNames)
|
||||||
|
{
|
||||||
|
AreaNames = new string[] { area1, area2 }.Concat(areaNames).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string[] AreaNames { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||||
|
|
||||||
|
namespace ApplicationModelWebSite
|
||||||
|
{
|
||||||
|
public class MultipleAreasControllerConvention : IApplicationModelConvention
|
||||||
|
{
|
||||||
|
public void Apply(ApplicationModel application)
|
||||||
|
{
|
||||||
|
var controllerModels = new List<ControllerModel>();
|
||||||
|
foreach (var controller in application.Controllers)
|
||||||
|
{
|
||||||
|
var areaNames = controller.ControllerType.GetCustomAttributes<MultipleAreasAttribute>()?.FirstOrDefault()?.AreaNames;
|
||||||
|
controller.RouteValues.Add("area", areaNames?[0]);
|
||||||
|
for (var i = 1; i < areaNames?.Length; i++)
|
||||||
|
{
|
||||||
|
var controllerCopy = new ControllerModel(controller);
|
||||||
|
controllerCopy.RouteValues["area"] = areaNames[i];
|
||||||
|
controllerModels.Add(controllerCopy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var model in controllerModels)
|
||||||
|
{
|
||||||
|
application.Controllers.Add(model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,6 +18,8 @@ namespace ApplicationModelWebSite
|
||||||
options.Conventions.Add(new ApplicationDescription("Common Application Description"));
|
options.Conventions.Add(new ApplicationDescription("Common Application Description"));
|
||||||
options.Conventions.Add(new ControllerLicenseConvention());
|
options.Conventions.Add(new ControllerLicenseConvention());
|
||||||
options.Conventions.Add(new FromHeaderConvention());
|
options.Conventions.Add(new FromHeaderConvention());
|
||||||
|
options.Conventions.Add(new MultipleAreasControllerConvention());
|
||||||
|
options.Conventions.Add(new CloneActionConvention());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -25,6 +27,9 @@ namespace ApplicationModelWebSite
|
||||||
{
|
{
|
||||||
app.UseMvc(routes =>
|
app.UseMvc(routes =>
|
||||||
{
|
{
|
||||||
|
routes.MapRoute(name: "areaRoute",
|
||||||
|
template: "{area:exists}/{controller=Home}/{action=Index}");
|
||||||
|
|
||||||
routes.MapRoute(
|
routes.MapRoute(
|
||||||
name: "default",
|
name: "default",
|
||||||
template: "{controller}/{action}/{id?}");
|
template: "{controller}/{action}/{id?}");
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
This is the help page
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
This is the more help page
|
||||||
Loading…
Reference in New Issue