1

I'm using ASP.NET Core MVC and using attribute routing in my controllers.

In my Configure method in Startup.cs I currently call app.UseMvc() to start my MVC application.

Everything works as expected.

Now I'm trying to get a catchall going, but the 404 always gets the best of the situation.

I changed my app.UseMvc to the following:

app.UseMvc(routes =>
{
    routes.MapRoute("Default",
                    "{*catchall}",
                    new { controller = "Index", action = "Index" },
                    new { catchall = @"^(.*)?$" });
});

but no dice.

I even tried to remove the catchall regular express as well, but I still get forwarded to my 404 page.

Any help is appreciated!

5
  • Confirm that you have an IndexController with Index() action Commented Apr 26, 2016 at 16:01
  • I do. my IndexController has [Route("")] and it has a method Index() that is setup as follows: [HttpGet] public IActionResult Index() { return View(); } Commented Apr 26, 2016 at 16:05
  • 2
    I think you are mixing up the convention based routing and attribute routing. Your catch all will apply to controllers that don't use attribute routing. Is this for a web api controller or mvc controller. Commented Apr 26, 2016 at 16:14
  • MVC controller How can I have a catchall for my attribute routing Commented Apr 26, 2016 at 16:18
  • Take a look at this article and see if it gives you any ideas. stephenwalther.com/archive/2015/02/07/… I've done something for catch all but it was for the previous version of mvc, not core Commented Apr 26, 2016 at 16:31

4 Answers 4

1

For anyone having the same problem, Tom Droste pushed me into the right direction

Adding a conventional route and using attribute routing has subtle side effects The catch-all route was added first in the route dictionary and the attribute routes are added afterwards.

The AttributeRouting class just creates an instance of AttributeRoute which is an IRouter responsible for building the attribute routes. This is done on the first time AttributeRoute is invoked

Having that, the catchall was thus never called because it's not the last route. putting everything back into conventional routing fixed the problem.

I suggest reading https://luisfsgoncalves.wordpress.com/2015/08/18/asp-net-5-routing-part-ii/ to understand how attribute routing works

Sign up to request clarification or add additional context in comments.

Comments

0

Have you tried this?

routes.MapRoute(
    "Default",
    "{*.}",
     new { controller = "Home", action = "Index" } 
);

1 Comment

Yes, this is the same as removing the regular expression from what I posted above.
0

In your Startup.cs file, place this line of code just above app.UseMvc() in the Configure() Method. Obviously you can redirect to whatever page you want.

app.UseStatusCodePagesWithRedirects("~/Home/Index");

EDIT:
Per you comment, as far as I know, you'd have to write your own middleware to redirect and keep the original url/query parameters. If you're not familiar with developing middleware, I posted a demo project on GitHub that demonstrates how to develop middleware in three easy steps. You can download the project here.

3 Comments

That works.. however, how can I keep the query parameters and what not? like lets say I go to /thispage/doesnot/exist it will redirect to ~/Home/Index, but I want to keep /thispage/doesnot/exist in the url...
Cool looks interesting! will have a look. The question I have is that why isn't the default route being applied though?
It could be a bug. There are plenty of those in RC1. I couldn't get it to work either.
0

So if I understand you correctly you just want a route that will be the one when the rest isn't matched. In my knowledge there are atm two ways to fix this. The correct one would be to write some routing middleware, however the dirty solution is to create a route with all nullable arguments that will be matched as last.

routes.MapRoute(
     "DirtyRoutingSolution",
     "{notUsed?}/{notUsedTwo?}/{notUsedThree?}/{notUsedFour?}",
     new { controller = "Home", action = "Index"}
);

7 Comments

Correct, I want that if a route /ABC doesn't exist that it loads / instead but keeps /ABC in the url. Basically any unmatched route should load my default
If thats the case, this is the quick and dirty solution to do that. Just create the amount of "notused?" as your longest url is. This way it will catch everything.
I copied pasted exactly what you wrote above, and if i put /ABC, it still brings me to the 404 page... seems that this route is never called. Is conventional routing set before attribute routing? Technically this route should be the last to work, correct me if I'm wrong
Yes, this should be the last route in line. I've created a test project and with me it works fine. Please create a test action in the home controller and put a breakpoint with it. This way you can see if its the route that isn't working or a other route picks it up. If it's the route, let me know. Then I need to fix my own project also XD
@Domze Any progress?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.