Fix mixed route for action error message
This commit is contained in:
parent
56bbb215ec
commit
4cd3012886
|
|
@ -721,8 +721,14 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
{
|
{
|
||||||
var routeTemplate = action.AttributeRouteInfo?.Template ?? nullTemplate;
|
var routeTemplate = action.AttributeRouteInfo?.Template ?? nullTemplate;
|
||||||
|
|
||||||
var verbs = action.ActionConstraints.OfType<HttpMethodActionConstraint>().FirstOrDefault()?.HttpMethods;
|
var verbs = action.ActionConstraints?.OfType<HttpMethodActionConstraint>()
|
||||||
var formattedVerbs = string.Join(", ", verbs.OrderBy(v => v, StringComparer.Ordinal));
|
.FirstOrDefault()?.HttpMethods;
|
||||||
|
|
||||||
|
var formattedVerbs = string.Empty;
|
||||||
|
if (verbs != null)
|
||||||
|
{
|
||||||
|
formattedVerbs = string.Join(", ", verbs.OrderBy(v => v, StringComparer.OrdinalIgnoreCase));
|
||||||
|
}
|
||||||
|
|
||||||
var description =
|
var description =
|
||||||
Resources.FormatAttributeRoute_MixedAttributeAndConventionallyRoutedActions_ForMethod_Item(
|
Resources.FormatAttributeRoute_MixedAttributeAndConventionallyRoutedActions_ForMethod_Item(
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,6 @@ using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Internal;
|
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNetCore.Mvc.Routing;
|
using Microsoft.AspNetCore.Mvc.Routing;
|
||||||
using Microsoft.AspNetCore.Routing.Tree;
|
using Microsoft.AspNetCore.Routing.Tree;
|
||||||
|
|
@ -775,6 +773,49 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
VerifyMultiLineError(expectedMessage, exception.Message, unorderedStart: 1, unorderedLineCount: 2);
|
VerifyMultiLineError(expectedMessage, exception.Message, unorderedStart: 1, unorderedLineCount: 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify that the expected exception and error message is thrown even when the user builds the model
|
||||||
|
// incorrectly.
|
||||||
|
[Fact]
|
||||||
|
public void AttributeRouting_ThrowsIfAttributeRoutedAndNonAttributedActions_OnTheSameMethod_UsingCustomConvention()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var controllerTypeInfo = typeof(UserController).GetTypeInfo();
|
||||||
|
var controllerTypeProvider = new StaticControllerTypeProvider(new[] { controllerTypeInfo });
|
||||||
|
var options = new TestOptionsManager<MvcOptions>();
|
||||||
|
options.Value.Conventions.Add(new TestRoutingConvention());
|
||||||
|
var modelProvider = new DefaultApplicationModelProvider(options);
|
||||||
|
var provider = new ControllerActionDescriptorProvider(
|
||||||
|
controllerTypeProvider,
|
||||||
|
new[] { modelProvider },
|
||||||
|
options);
|
||||||
|
var assemblyName = controllerTypeInfo.Assembly.GetName().Name;
|
||||||
|
var expectedMessage =
|
||||||
|
"The following errors occurred with attribute routing information:"
|
||||||
|
+ Environment.NewLine
|
||||||
|
+ Environment.NewLine
|
||||||
|
+ "Error 1:"
|
||||||
|
+ Environment.NewLine
|
||||||
|
+ $"A method '{controllerTypeInfo.FullName}.GetUser ({assemblyName})'" +
|
||||||
|
" must not define attribute routed actions and non attribute routed actions at the same time:"
|
||||||
|
+ Environment.NewLine +
|
||||||
|
$"Action: '{controllerTypeInfo.FullName}.GetUser ({assemblyName})' " +
|
||||||
|
"- Route Template: '(none)' - " +
|
||||||
|
"HTTP Verbs: ''"
|
||||||
|
+ Environment.NewLine
|
||||||
|
+ $"Action: '{controllerTypeInfo.FullName}.GetUser ({assemblyName})' " +
|
||||||
|
"- Route Template: 'Microsoft/AspNetCore/Mvc/Internal/User/GetUser/{id?}' - " +
|
||||||
|
"HTTP Verbs: ''" + Environment.NewLine +
|
||||||
|
Environment.NewLine +
|
||||||
|
"Use 'AcceptVerbsAttribute' to create a single route that allows multiple HTTP verbs and defines a " +
|
||||||
|
"route, or set a route template in all attributes that constrain HTTP verbs.";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var exception = Assert.Throws<InvalidOperationException>(() => provider.GetDescriptors());
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
VerifyMultiLineError(expectedMessage, exception.Message, unorderedStart: 1, unorderedLineCount: 2);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void AttributeRouting_RouteOnControllerAndAction_CreatesActionDescriptorWithoutHttpConstraints()
|
public void AttributeRouting_RouteOnControllerAndAction_CreatesActionDescriptorWithoutHttpConstraints()
|
||||||
{
|
{
|
||||||
|
|
@ -2063,5 +2104,36 @@ namespace Microsoft.AspNetCore.Mvc.Internal
|
||||||
application.ApiExplorer.IsVisible = _isVisible;
|
application.ApiExplorer.IsVisible = _isVisible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TestRoutingConvention : IApplicationModelConvention
|
||||||
|
{
|
||||||
|
public void Apply(ApplicationModel application)
|
||||||
|
{
|
||||||
|
foreach (var controller in application.Controllers)
|
||||||
|
{
|
||||||
|
var hasAttributeRouteModels = controller.Selectors
|
||||||
|
.Any(selector => selector.AttributeRouteModel != null);
|
||||||
|
if (!hasAttributeRouteModels)
|
||||||
|
{
|
||||||
|
var template = controller.ControllerType.Namespace.Replace('.', '/')
|
||||||
|
+ "/[controller]/[action]/{id?}";
|
||||||
|
var attributeRouteModel = new AttributeRouteModel()
|
||||||
|
{
|
||||||
|
Template = template
|
||||||
|
};
|
||||||
|
|
||||||
|
controller.Selectors.Add(new SelectorModel { AttributeRouteModel = attributeRouteModel });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class UserController : Controller
|
||||||
|
{
|
||||||
|
public string GetUser(int id)
|
||||||
|
{
|
||||||
|
return string.Format("User {0} retrieved successfully", id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue