Angular 2 - Routing with ASP.NET MVC - asp.net-mvc

I am trying to use ASP.NET MVC (not core) with AngularJS 2 and having some issues with the routing.
First in RouteConfig.cs, I have following routes defined
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
// when the user types in a link handled by client side routing to the address bar
// or refreshes the page, that triggers the server routing. The server should pass
// that onto the client, so Angular can handle the route
routes.MapRoute(
name: "spa-fallback",
url: "{*url}",
defaults: new { controller = "Home", action = "Index" }
);
In my app.route.ts (angular routes), I have just defined a couple of routes. My default route redirects to the other route like
export const router: Routes = [{
path: '',
redirectTo: 'auctions/e231',
pathMatch: 'full'
},
{
path: 'auctions/:id',
component: AuctionComponent,
children: []
}
];
When I run the application, my server route /Home/Index is served up fine which loads the angular application and default route in my app.route.ts redirects me to auctions/e231 and my browser's final URL becomes
http://localhost:53796/auctions/e231
Everything works as expected but when I refresh the page with this URL, I get a server error for resource not found, which is also expected because it looks for a Controller named Auctions which is not present in MVC. I want to know why my spa-fallback route in RouteConfig.cs doesn't picked up? Also is there a better way to handle this scenario in asp.net mvc because I want to able to use some of my MVC controller's actions like /Account/Login and others.

The problem is that when you refresh the page, the first route will be used, because it will try to get a controller with name Auctions. If you remove that first route configuration (Default) and only use the second (spa-fallback), it will work ok, that's how I used in my projects, only put before spa-fallback other mvc routes that you want to redirect to other mvc controllers.

Although not the best approach in my opinion but worked nevertheless. I made it work using the constraints in my route. I updated my default route to:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { controller = "Home|Account|Upload|Resource" } // this is basically a regular expression
);
Where I only had 4 MVC controllers (Home, Account, Upload, Resource). My spa-fallback route is under the default one so if we type anything other than these controller names, angular will try to find it in its route with the default /Home/Index server path.
I hope it helps someone.

Related

Can I have a default.aspx page in an MVC site?

I've got a legacy WebForms site with a Default.aspx page that's configured in IIS to be the default page. So when someone goes to mysite.com they see mysite.com/Default.aspx, but the url in the address bar only shows the mysite.com.
I added MVC to the site, and I want to gradually move functionality to MVC. Everything works, but it broke the root page: navigating to the route caused a 404 because the default route was matching the root and trying to route a the Home controller, but there wasn't one. So I added one that does this:
' GET: /Home
Function Index() As ActionResult
'jump to the go page
Return Redirect("/default.aspx")
End Function
This now works, except that when you navigate to the route, it shows mysite.com/Default.aspx in the address bar.
I'd like it if either:
I could NOT match the root route, and let the WebForms Default.aspx page handle it as before
I could route as I'm doing now, but make it so the Default.aspx page was not displayed in the address bar.
Are either of these possible?
It is possible.
In your route configuration, remove the controller in the defaults parameter.
From this:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
To this:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { action = "Index", id = UrlParameter.Optional }
);
Then add the Default.aspx to your project root

ASP.NET MVC4 Routing - Multiple routes to the same location

I am in the process of setting up a Single Page Application (SPA) and would like to setup, currently two routes. For instance:
Route 1: http://localhost - this is the default route which requires authentication (Admin area)
Route 2: http://localhost/<client>/<clients project name>/ - this does not require authentication (view only)
In the admin area, they setup the <client> and <clients project name>, therefore I know I need to setup this configuration in MVC4 Routes, but it is unclear to me how I would approach this.
Another caveat would be, if the <clients project name> was not entered into the URL, it would present a search page for that client.
One of the great things about routing in MVC is the ability to route anything to anywhere, regardless of whether the url matches the naming of controllers and action methods. The RouteConfig allows us to register specific routes to cater for this. Let me show you how you can achieve this.
Route 1:
This is handled by the default route in the route config.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home",
action = "Index",
id = UrlParameter.Optional });
Hitting http://localhost will take you to the Home controller and the Index action method.
Route 2:
We can set up one route that will cater for http://localhost/<client> and http://localhost/<client>/<clients project name>
routes.MapRoute(
"Client",
"{client}/{title}",
new { controller = "Home",
action = "Client",
title = UrlParameter.Optional });
Hitting either http://localhost/bacon or http://localhost/bacon/smokey will take you to the Home controller and the Client action method. Notice the title is an optional parameter this is how we can get both urls to work with the same route.
For this to work on the controller end our action method Client would need to look like this.
public ActionResult Client(string client, string title = null)
{
if(title != null)
{
// Do something here.
}
}

Why is my area routing failing for one controller but not another?

I have an MVC 4 site with the usual default routes defined (including an API route), plus an area for administration functions, which has its own route. The routing configuration looks like this:
Default Route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "MyProject.Controllers" }
);
Default API Route:
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Admin Area Route (in the area registration code):
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "MyProject.Areas.Admin.Controllers" }
);
Additionally, the admin area has it's own Layout page for the views.
The routes for the main site all work correctly (including the HTTP routes for the API controllers), but the routes for the Admin area show some odd behaviour. Requests made to the home controller in the admin area succeed, whilst requests to other controllers in the admin area do not. The error that I get is
System.Web.HttpException: The controller for path '/admin/concerts' was not found or does not implement IController.
The interesting thing is that the stack trace associated with the exception contains code from the main Layout page, rather than the admin area's Layout page, which I think suggests that the request has been routed to the default route rather than the admin route.
I've tried debugging the route configuration with Glimpse, but haven't had much luck, other than to confirm through a second medium that the route works correctly for the admin area's HomeController, but not for other controllers in the area.
Update:
I have the following relevant controllers defined:
Default Route:
MyProject.Controllers.ConcertsController
MyProject.Controllers.HomeController
(Some others, not relevant here.)
Default HTTP Route:
MyProject.Controllers.Api.ConcertsController only
Admin Area Route:
MyProject.Areas.Admin.Controllers.ConcertsController; and
MyProject.Areas.Admin.Controllers.HomeController only
This turned out not to be a routing issue at all, but instead a problem with the view definitions: each of the ConcertsController views included a Layout statement pointing the view at the Layout for the main site.

/Mappings/Index is found but not /Mappings with ASP.NET MVC

Just struggling with a simple issue with ASP.NET MVC. I have a list of views, each view associated with an Index.aspx view being associated by default with /MyView.
Yet, for some reason I have 1 view named /Mappings that does not work (404 resource is not found) whereas the explicit path /Mappings/Index works.
I have the default route settings as provided by the default ASP.NET MVC sample
routes.MapRoute(
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
And, the default Index works for the other views of the same webapp.
Any idea what could be wrong here?
You have to define default action if it is not provided:
route.MapRoute(
"Default", // Route name
"{controller}/{action}", // URL with parameters
new { action = "Index" } // Default action if not provided
);
EDIT:
Look at this link:
http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx
You can use this debugger to test your routing.

Default.aspx not getting executed in ASP.NET project with MVC sections

My app is mainly an ASP.NET app that I'm adding an MVC section to it.
My Default.aspx (no codebehind) page has a simple Response.Redirect to a StartPage.aspx page but for some reason MVC is taking over and I'm not getting to the StartPage.aspx page. Instead I get routed over to my first and only MVC section which is a registered route that I've registered in the global.asax.cs page (Albums).
Is there a way to tell MVC to leave my requests to the root "/" to be my IIS 7 default document...in this case Default.aspx?
This is what is in my RegisterRoutes:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("Albums","{controller}/{action}/{id}",
new { controller = "Albums", action = "Index", id = "" });
If you remove the default controller from your second route there, it won't match against "/" anymore and Routing will ignore requests for "/", leaving them for the usual ASP.Net pipeline to handle
So, change your routes to:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("Albums","{controller}/{action}/{id}",
new { action = "Index", id = "" });
That should solve your problem!
The default.aspx page is being served by IIS because it is the default document. MVC would
let the default.aspx page handle the request, if it realized that the request was for default.aspx (e.g. "http://foo.com/default.aspx"). It doesn't relize that though in this scenario ("http://foo.com") so you could add this before the default route to achieve what you are after
// ignore "/"
routes.IgnoreRoute("");
// default route
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index",
id = UrlParameter.Optional } // Parameter defaults
);
You could tell the MVC to ignore the Default.aspx like this:
routes.IgnoreRoute("Default.aspx");

Resources