Correct me on URL routing in MVC issue - c#

This is related my question which i asked in this link correct me on url routing in mvc
Now i came with another problem, so i thought i will ask it as new question.
Now i have following routes in my global.asax file
routes.MapRoute(
"Custom", // Route name
"{action}/{id}", // URL with parameters
new { controller = "Authentication", action = "BigClientLogin", id = UrlParameter.Optional } // Parameter defaults
);
and
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Authentication", action = "BigClientLogin", id = UrlParameter.Optional } // Parameter defaults
);
Now what happens is when i run my solution the URL i am getting is http://localhost:65423/Login this is what i need for my Login Page that is OK. But when i login in as user i am getting "The resource cannot be found" error.
when i checked it i can see that my URL is now changed to http://localhost:65423/Admin/Dashboard
So i think this causing the issue. So this looks the problem related to my global.asax routing.
Can anyone help me to find out what i did wrong.

You have 2 routes with completely optional segments. The issue is that there is no way for the routing framework to differentiate between them.
The only way you can make it work with your existing routes is to specify them explicitly by name (such as when using #Html.RouteLink or #Html.RouteUrl).
#Html.RouteLink("Custom Link 1", "Custom", new { action = "BigClientLogin" })
#Html.RouteLink("Custom Link 2", "Custom", new { action = "Action2" })
#Html.RouteLink("Home Page", "Default", new { controller = "Home", action = "Index" })
#Html.RouteLink("About", "Default", new { controller = "Home", action = "About" })
Doing it that way will function, but is not normal. Typically, there is only one route configured with all defaults for the controller, action, and id and the rest have some explicitly declared segments and/or constraints (segments being preferable).
routes.MapRoute(
"Custom", // Route name
"Custom/{action}/{id}", // URL with parameters
new { controller = "Authentication", action = "BigClientLogin", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Authentication", action = "BigClientLogin", id = UrlParameter.Optional } // Parameter defaults
);
The first route will now only match when the URL starts with /Custom/. If it does not start with custom, it will match the default route.
The trick is to ensure that the routes are listed in the right order and that they only match the URL in specific cases, letting them pass on to the next route in the list if the case is not correct.

It happens because of 2 things.
1st the sequence of Your route
2nd your defaults
So if you end up on 'admin/dashboard' that's not a default, guess you've just put it in your studio to start there?
To get to http://localhost:65423/Login you'll need an action on Your AuthenticationController called 'Login' but it looks like the one You have configured is 'BicClientLogin' so You won't be taken to login unless you specify it, and at that time it has to exist.
To Help You further we need to know what controllers You have and what actions there exists, plus if security is part of your solution and if in case, what is is set to use.

Related

Routing config issue cannot be resolved

Given this URL's
http://localhost:51095/Person // This is equivalent to this one Person/Index
http://localhost:51095/Person/Allan
I setup a route config for it as follows :
routes.MapRoute(
"Person",
"Person/{personName}",
new { controller = "Person", action = "Person", personName = UrlParameter.Optional }
)
;
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
First URL should follow the Default route and the second should follow the Person route.
This is not working because the first config seems to catch all these URL's
The first thing I'd do is remove personName = UrlParameter.Optional in the first Route. This would allow only urls that provide a personName value to access this Route. If no value is provided, it should fall through to the default Route.
But you'd want to think about the future with this strategy: if you implement new actions on that Person controller, you'd need to add a new Route for each of them. If you had a new 'Edit' action for example:
routes.MapRoute(
"Person_Edit",
"Person/Edit/{personName}",
new { controller = "Person", action = "Edit" }
)
You'd want to add these new Routes before the first one though - ordering/precedence of Routes is important.

MVC routing vs. partial class

I have a request controller that is getting out of hand, and I want to divide the actions on several controllers while maintaining a clean URL. I'm trying to experiment with routing, but without success. I've read some examples and tutorials on routing, but, though I understand the examples, nothing seems to apply to my case, and I feel non the wiser. What I want is for the URL Requests/Approval to be handled on my ApprovalController instead of my RequestController, so I wrote the following.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Approval",
"Request/{controller}/{action}",
new { controller = "Approval", action="Index", id = "" }
);
}
But it's not working. Why? I have a folder in the my Views called Approval, and in there I have a file called Index.cshtml. How should I code the MapRoute?
Edit
I added all the routes I've got
You need to swap the two MapRoute statements, like so:
routes.MapRoute(
"Approval",
"Request/Approval/{action}",
new { controller = "Approval", action="Index", id = "" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
The reason it is currently not working is because the first statement ('Default' route name) is getting matched before the second one is even evaluated.
In addition (as noted in my above example,) you need to remove '{controller}' in the Approval route and replace with 'Approval'... unless you specifically want the URL /Request/{ANY controller}/{action} to go through, which I doubt. From your question it seems you only want /Request/Approval/ to go to your Approval controller.
Don't forget to keep the Default route at the bottom, so as to match your other controllers and actions. It serves as a catch-all should no other matches exist.
The order you map your routes matters. Move the second route before the default route.
You will still have a problem though, as any thing /request/something will look for the SomethingContoller. To fix this, change your route to this:
routes.MapRoute(
"Approval",
"Request/Approval/{action}",
new { controller = "Approval", action="Index", id = "" }
);

Pass parameters through URL in an ASP.NET MVC Application

I need to access a parameter without name.
Ex: I have a controller test, I want to get "data" in mysite.com/test/data. Without calling the action data.
I know how to do that passing it though Index action.
public ActionResult Index(string id)
That way I'd only need to type mysite.com/test/Index/data to get "data", but I don't want to have to type Index.
Does anyone know how to do it?
EDIT:
Thanks a lot to #andyc!
AndyC I used what you said and created a test. It worked =D
Now I can type mysite.com/something and if something is not an controller it redirects to my profile page.
This is what is working for me
routes.MapRoute(
"Profile",
"{id}",
new { Controller = "Profile", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
Setup a custom route
In your global.asax file, put (Inside the RegisterRoutes method):
routes.MapRoute(
"MyShortRoute",
"view/{id}",
new { Controller = "test", action = "Index" }
);
The first parameter is a name, the second is the URL format and the last parameter is the default values (in this case if you leave id empty it'll default to id 0.
Notice that I don't use test/{id} as this would also match test/Edit, where edit is an action that you do not want passed as a parameter (I can't think of another way to avoid this, especially if you're using strings instead of ints for your parameters).
Remember to order your routes appropriately in your global.asax file. Put more specific routes before less specific routes. When the system is searching for a route to take, it does not attempt to find the most specific match but instead it starts from the top, and uses the first match it finds.
Therefore, this is bad:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "test", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
"Specific",
"test/{id}",
new { controller = "test", action = "Index", id = 0 }
);
In this example, if you browse to test/somevalue it will match the FIRST entry, which is not what you want, giving you the testcontroller and the somevalue action.
(As your adding a more specific route, you will want it near the top, and definitely before your default).

MVC Routing problem

I am learning MVC and I need to understand why it doesn't work the way it should.
Here is my routing :
public static void RegisterRoutes(RouteCollection routes)
{
// Note: Change the URL to "{controller}.mvc/{action}/{id}" to enable
// automatic support on IIS6 and IIS7 classic mode
//http://localhost/store/category/subcategory/product
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Category", // Route name
"store/{category}/{subcategory}", // URL with parameters
new
{
controller = "Catalog",
action = "Index",
category = "Featured Items",
subcategory = "All Items"
}
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" }, // Parameter defaults
new { controller = #"[^\.]*" } // Parameter constraints
);
}
The way I understand routing I should see the following url when I start the web app :
http:/localhost/store/
What I get is the second route....
Furthermore if I change the second route to "home/{action}/{id} it doesn't catch any routes.
Could you help me understand this please..Thanks
Routes do not specify default URL; the default URL is handled by your app. Routing specifies that when it sees http://localhost/store/bikes/mountain, it will use the catalog controller. But that doesn't specify the default URL; you have to enter that in the project properties.
I would recommend not changing the second one because unless you are creating groupings for all of your controllers, it's best to have the default as it is so you can catch all URL's. Your change to the second one would require the url to be:
http://localhost/home/home/index to match the HomeController's index action, whereas the default setup catches http://localhost/home/index...
Does that make sense?
Try this: http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx

How can I create a friendly URL in ASP.NET MVC?

How do I generate friendly URLs within the ASP.NET MVC Framework? For example, we've got a URL that looks like this:
http://site/catalogue/BrowseByStyleLevel/1
The 1 is Id of the study level (Higher in this case) to browse, but I'l like to reformat the URL in the same way StackOverflow does it.
For example, these two URLs will take you to the same place:
https://stackoverflow.com/questions/119323/nested-for-loops-in-different-languages
https://stackoverflow.com/questions/119323/
EDIT: The friendly part of the url is referred to as a slug.
There are two steps to solve this problem. First, create a new route or change the default route to accept an additional parameter:
routes.MapRoute( "Default", // Route name
"{controller}/{action}/{id}/{ignoreThisBit}",
new { controller = "Home",
action = "Index",
id = "",
ignoreThisBit = ""} // Parameter defaults )
Now you can type whatever you want to at the end of your URI and the application will ignore it.
When you render the links, you need to add the "friendly" text:
<%= Html.ActionLink("Link text", "ActionName", "ControllerName",
new { id = 1234, ignoreThisBit="friendly-text-here" });
This is how I have implemented the slug URL on my application.
Note: The default Maproute should not be changed and also the routes are processed in the order in which they're added to the route list.
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home",
action = "Index",
id = UrlParameter.Optional
} // Parameter defaults
);
routes.MapRoute("Place", "{controller}/{action}/{id}/{slug}", new { controller = "Place", action = "Details", id = UrlParameter.Optional,slug="" });
you have a route on the global.asax
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = ""}
// Parameter defaults )
you can define your own route like :
controller is the cs class inside the the controllers folder.
you can define your id - with the name you choose.
the system will pass the value to your actionResult method.
you can read more about this step here : http://www.asp.net/learn/mvc/tutorial-05-cs.aspx

Categories

Resources