vaindil vaindil - 3 months ago 18
C# Question

Routing doesn't work without attributes

EDIT: An issue has been opened on GitHub to clarify the docs with the information in the answer.

I'm trying to set up routing in my .NET Core MVC app (for an API). I believe I have everything configured correctly, but no routes work (all return 404) unless the action has a routing attribute explicitly set. This same problem is mentioned here, but he doesn't know what fixed the problem.


I put the attributes back on, it worked. I removed them, it didn't. Eventually through some magical incantation of removing and re-adding route configuration - switching it off and back on again in other words -
UseMvcWithDefaultRoute()
worked without routing attributes. Not sure what happened there.


Here is a simplified version of what I have. What's the problem? Why isn't routing working without attributes set?

In this example, I'm attempting to
POST
to
/login/register
.

Startup.cs
:

public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
})
.AddJsonOptions(options =>
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver());

public void Configure(IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseDefaultFiles();
app.UseStaticFiles();

app.UseMvcWithDefaultRoute();
}


I also tried specifying the route manually:

app.UseMvc(routes =>
{
routes.MapRoute(
"default",
"{controller=Home}/{action=Index}/{id?}");
});


Login controller:

[Route("[controller]")]
[AllowAnonymous]
public class LoginController : Controller
{
[HttpPost]
[Route("register")] // only works with this here
public IActionResult Register([FromBody]RegisterModel model)
{
return Ok();
}
}

Answer

The default {controller=Home}/{action=Index}/{id?} route will already map the controller and action to /Login/Controller. However, if you add a [Route] attribute on the controller, you indicate that you want to start building a new route and the default route will not apply anymore. Therefore you'll either have to remove the attributes from both the controller and action or add it to both. You might also want to use the [action] route token as well:

[Route("[controller]/[action]")]
[AllowAnonymous]
public class LoginController : Controller
{
   // ...
}
Comments