parent
7ba167fcd8
commit
b992ef0ced
2
Mvc.sln
2
Mvc.sln
|
|
@ -1,6 +1,6 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26730.10
|
||||
VisualStudioVersion = 15.0.26831.3000
|
||||
MinimumVisualStudioVersion = 15.0.26730.03
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{DAAE4C74-D06F-4874-A166-33305D2643CE}"
|
||||
EndProject
|
||||
|
|
|
|||
|
|
@ -166,5 +166,35 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
// Assert
|
||||
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;
|
||||
}
|
||||
|
||||
[CloneAction("MoreHelp")]
|
||||
public IActionResult Help()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
private class ActionName2Attribute : Attribute, IActionModelConvention
|
||||
{
|
||||
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.
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
|
||||
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 ControllerLicenseConvention());
|
||||
options.Conventions.Add(new FromHeaderConvention());
|
||||
options.Conventions.Add(new MultipleAreasControllerConvention());
|
||||
options.Conventions.Add(new CloneActionConvention());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -25,6 +27,9 @@ namespace ApplicationModelWebSite
|
|||
{
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
routes.MapRoute(name: "areaRoute",
|
||||
template: "{area:exists}/{controller=Home}/{action=Index}");
|
||||
|
||||
routes.MapRoute(
|
||||
name: "default",
|
||||
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