Can these routes co-exist? - asp.net-mvc

Can anyone tell me how (and what would be the best way) routes can be configured to allow the following URL's to co-exist in ASP.Net MVC 3?
/Product/a38e8843-195f-4ee8-b89a-2549b753a307
maps to Index action on ProductController width id = a38e8843-195f-4ee8-b89a-2549b753a307
/MemberShip/LogOn
maps to LogOn action on MemberShip controller
I figure I'll have to somehow have to do some configuration based on the specific controller - I just don't know how! :)

You should add the following routes before the default routes:
"Products/{productId}" and "MemeberShip/{action}"
Each one pointing to its specific controller and action.
Create your actions normally:
public class Products : Controller
{
public Action ViewProduct(string productId)
{
...
public class Membership : Controller
{
public Action Logon()
{
...
And when mapping your routes, add two specific routes:
routes.MapRoute(
"ViewProduct",
"Products/{productId}",
new { controller = "Products", action = "ViewProduct"}
);
routes.MapRoute(
"Logon",
"Membership/{action}",
new { controller = "Membership"}
);
If you are using the default routes, this last one isn't necessary, because it is on the pattern "controller/action".
Here you can find a lot of tutorials on MVC, and surely, routing:
http://www.asp.net/mvc/tutorials/asp-net-mvc-overview-cs

Related

generate url with Url.Action helper from attribute routing controller with prefix

i have definned a Map route like this:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=User}/{action=Student}/{id?}");
});
and i have an API Action with Attribute routing like this:
[Route("api/User")]
public class UserApiController : Controller
{
....
[HttpGet]
[Route("Teacher")]
public async Task<IEnumerable<UserApiVM>> GetTeachers()
{
....
}
}
Which i can access browsing to a direct url like "http://api/User/Teacher".
Now i whant to generate that url using the #URL.Action helper or any other helper, but i can't figure out how. I tried with
#Url.Action("Teacher","UserApi")
but it couldn't find the controller.
BTW, the controller is Controllers are in a folder called "Controllers", and the API controllers in a folder called "API" inside the "Controllers" folder.
Thanks!
For generating api/User/Teacher, you need to specify GetTeachers as controller name instead of Teacher.
#Url.Action("GetTeachers", "UserApi")
If you want to generate URL by specifying Teacher, you could try to set route name like below:
[HttpGet]
[Route("Teacher",Name = "Teacher")]
public async Task<IEnumerable<string>> GetTeachers()
{
return null;
}
And generate URL by:
#Url.RouteUrl("Teacher")

Default route not working in Asp.Net Core

I have the following Controller & Action that I want to be the first page that is loaded when the user enters my webapp:
[Route("auth")]
public class AuthController : Controller
{
[Route("signin")]
public IActionResult SignIn(bool signInError)
{
}
}
I try to do this in my app.UseMvc options like so:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=auth}/{action=signin}/");
});
However, when I start my webapp it simply navigates to http://localhost:52608/.
If I type in http://localhost:52608/auth/signin?ReturnUrl=%2F the webpage loads correctly on the page I want to be on when the user starts the webapp.
My question is, how do I set this up so it can navigate to this page as soon as the user opens the webapp?
Mixed Routing It is perfectly valid to use convention-based routing
for some controllers and actions and attribute routing for others.
However, ASP.NET Core MVC does not allow for convention-based routes
and attribute routing to exist on the same action. If an action uses
attribute routing, no convention-based routes can map to that action.
See the ASP.NET Core docs for more info.
More info about routing
So if you want to use attribute routing, then You can't map default path in convention based routing.
If you need to use attribute routing in this controller you can add redirect action in web.congig file.
Or just remove attribute routing from that action and it will work:
public class AuthController : Controller
{
public IActionResult SignIn(bool signInError)
{
}
}
Edit:
Easiest solution:
Add new controller with redirect action for example:
public class HomeController : Controller
{
public IActionResult Index()
{
return new RedirectToActionResult("SignIn", "Auth", new {signInError = false});
}
}
And add default routing to this Controller
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=home}/{action=index}/");
});
There is a separate field for defaults.
routes.MapRoute(
name: "default",
template: "{controller}/{action}",
defaults: new { controller = "auth", action = "signin" }
);

Name of class, action and controller

in the mvc web application url
http://www.myserver.com/movies/titles/19
I think the name of the action is 'titles'
The name of the controller is 'movies'
but which of the items is the class from the url?
Using any one of the default templates from Asp.Net MVC (assuming routes are setup correctly) then:
http://www.myserver.com/movies/titles/19
and assuming:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home",
action = "Index",
id = UrlParameter.Optional });
The controller would look like:
// Controller class and 'name'
public class MoviesController
{
public ActionResult Titles (int id)
{
// id = 19 with the example above
return View();
}
}
There is no hard rule what the parts of the URL has to be, but with the default routes the name of the controller would be MoviesController and the name of the action method would be Titles.
It's usual for an action to use a view, which would also have the name Titles unless you specify something else. The view has a model, and if that model is defined as a specific type in the view header, it would usually be something like TitlesModel.
But those are all conventions, you could add a route that matches that URL and specifies a different controller and action if you like. The action could do whatever it likes to return a response, it doesn't actually have to use a view at all.

ASP.NET MVC 3 remove /Home

I've created a new ASP.NET MVC 3 internet application in Visual Web Developer 2010 Express, and I have noticed that with this default template, the path localhost:port/Home shows the same content as localhost:port/
Is there a way to remove the /Home? I would only like localhost:port/ to be the landing page.
Both urls work because that's how the default route has been defined in Global.asax:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
This means that all of /, /Home and /Home/Index will land to the HomeController/Index action. So in fact when you are request / it is the exact same action being executed.
You can modify it like so:
routes.MapRoute(
"Default",
"{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Of course by doing this the only controller and action you will ever be able to run in your application will be the HomeController and Index action. No other action or controller will be ever accessible as you don't provide any means in the url to specify them. So I would leave the default routes as is because they allow to handle 99% of the cases unless you have some specific requirements.
The other guys are correct. However they dont really tell you a way around it. One way to get better control of the routes is as follows
Do something like below in the Register routes method
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
var controllers = typeof(MvcApplication).Assembly.GetTypes().Where(t => !t.IsAbstract && t.Navigate(_ => _.BaseType).Any(_ => _ == typeof(Controller)));
foreach (var controller in controllers)
{
var actions = controller.GetMethods().Where(m => m.HasAttribute<RouteAttribute>()).Select(m => new { Method = m, Attribute = m.GetAttribute<RouteAttribute>() }).ToArray();
foreach (var action in actions.OrderBy(m => m.Attribute.Path.Count(c => c == '{')))
routes.MapRoute(string.Format("{0}.{1}", controller.Name, action.Method.Name), action.Attribute.Path.TrimStart('/'), new { controller = controller.Name.Replace("Controller", ""), action = action.Method.Name });
}
and then decorate your controller methods with a route attribute that defines exactly what the route should be. You have to make the route attribute yourself, it cna be pretty simple just an attribute with a string parameter . In this fashion you can set any controller method to have any route you like.

ASP NET MVC Route - Not Found

I'm having problems when using this route:
routes.MapRoute("ProductIndex", "pr-{key}", new { controller = "Home", action = "Product" });
When the key contains 'pr-', the route doesn't work.
Example: http://.../pr-my-product-key-with-pr-key
Routes don't work the way you want them to work, but it's easily converted
change your route to:
routes.MapRoute(
"ProductIndex",
"pr/{key}",
new { controller = "Home", action = "Product" });
and use:
http://.../pr/my-product-key-with-pr-key
or, if you really want to use that "way" you need to override the Initialization method of your main controller are check the link with StartWith() and redirect to the proper Controller.

Resources