ASP.NET MVC: routing help - asp.net-mvc

Consider two methods on the controller CustomerController.cs:
//URL to be http://mysite/Customer/
public ActionResult Index()
{
return View("ListCustomers");
}
//URL to be http://mysite/Customer/8
public ActionResult View(int id)
{
return View("ViewCustomer");
}
How would you setup your routes to accommodate this requirement?
How would you use Html.ActionLink when creating a link to the View page?

In global.asax.cs, add following (suppose you use the default mvc visual studio template)
Route.MapRoute("Customer",
"Customer/{id}",
new { Controller = "CustomerController", action="View", id="" });
Make sure you put this route before the default route in the template
You then need to modify your controller. For the view,
public ActionResult View(int? id)
{
if (id == null)
{
return RedirectToAction("Index"); // So that it will list all the customer
}
//...The rest follows
}
For your second question, ActionLink is simple.
Html.ActionLink("Link Text", "View", "Customer", new {id=1}, null);

Related

Url.Action map a wrong link from Route attribute

This is target controller and action:
[RoutePrefix("Editor")]
public class EditorController : Controller
[HttpGet]
[Route("{id:int}")]
public ActionResult Edit(int id)
Map method calling:
#Url.Action("Edit", "Editor", new { id = page.Id})
result:
/Editor?id=1
required result:
/Editor/1
To achieve the result you want you have to use a route name:
[HttpGet]
[Route("{id:int}", Name = "EditorById")]
public ActionResult Edit(int id)
Then in your view you would use Url.RouteUrl instead of Url.Action:
#Url.RouteUrl("EditorById", new { controller = "Editor", Id = 1, action = "Edit" })
Hope this helps,
Have you checked if you have enabled MVC AttributeRoutes?
routes.MapMvcAttributeRoutes();
see http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx
I just faced with same problem. When i fixed the links - editing is broken (form always redirects to the same page).
Here is solution:
A link
#Html.ActionLink("Edit my nice object", "Edit", new { id=item.Id })
A form in the view Edit.cshtml (specifying Controller name is necessary!)
#using (Html.BeginForm("EditConfirmed", "AppServers"))
The actions in the controller
public class AppServersController
[Route("edit/{id:int?}")]
public ActionResult Edit(int? id)
{
// bla-bla
}
[Route("edit_confirmed")]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditConfirmed([Bind(Exclude = "Created,LastModified")] AppServerVM appServer)
{
if (!ModelState.IsValid) return View("Edit", appServer);
// bla-bla
}
}
Now both links and editing works.

ASP.NET MVC - Set different entry point to Web Aplication

I am developing an ASP.Net MVC Website which the expected routing behavior is like Facebook
When user is not logged in and access the site he is showed the welcome page under
www.domain.com/
If he logs in we want him to access the website content still in
www.domain.com/
How should i define the routes?
Edit: To clarify more as instructed
I want to serve a different Index action if a user is logged in and a different if he is not.
An approach that doesn't work
[Authorize]
public ActionResult Index()
{
return View();
}
[AllowAnonymous]
public ActionResult Index()
{
return View();
}
So with two different Index Actions the default Route
routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }
will perform as i want.
By looking in the MSDN Documentation i found out i can pass the name of the View i want in the constructor.For the sake of completeness here is my implementation.
public ActionResult Index()
{
if (User.Identity.IsAuthenticated)
{
return View();
}
else
{
return View("Welcome");
}
}

MVC multiple views for a single controller

Is it possible in MVC to do the following with a single controller "ListController" to take care of the following pages...
www.example.com/List/Cars/ForSale/{id} optional
www.example.com/List/Cars/ForRent/{id} optional
www.example.com/List/Search/
www.example.com/List/Boats/ForSale/{id} optional
www.example.com/List/Boats/ForRent/{id} optional
www.example.com/List/Boats/Search/
If not, is there any way to get around it besides making a CarsController and BoatsController separate? They will be using the same logic just would like the URLs different.
You can definitely do this. It is simple using routing. You can route the different urls to different actions in your controller.
Here are examples of defining some of the above urls:
routes.MapRoute("CarSale"
"/List/Cars/ForSale/{id}",
new { controller = "list", action = "carsale", id = UrlParameter.Optional } );
routes.MapRoute("ListSearch"
"/List/search",
new { controller = "list", action = "search"} );
routes.MapRoute("BoatSale"
"/List/Boats/ForSale/{id}",
new { controller = "list", action = "boatsale", id = UrlParameter.Optional } );
Then in your controller you would have action methods for each:
public ListController
{
// ... other stuff
public ActionResult CarSale(int? id)
{
// do stuff
return View("CarView");
}
public ActionResult BoatSale(int? id)
{
// do stuff
return View("BoatView");
}
// ... other stuff
}
Yes You can use multiple View in one Controller.
Let's take one Example,
I have one Controller Called Lawyers
public class LawyersController : Controller
{
// GET: Lawyers
public ActionResult Login()
{
return View();
}
public ActionResult Signup()
{
return View();
}
so I have one controller and 2 views.
Routes could also be specified above methods with decorators so no need for RouteConfig. You just need to omit the "controller/" part from the route.
public ListController
{
// ... other stuff
[Route("Cars/ForSale/{id}")]
public ActionResult CarSale(int? id)
{
// do stuff
return View("CarView");
}
[Route("Boats/ForSale/{id}")]
public ActionResult BoatSale(int? id)
{
// do stuff
return View("BoatView");
}
// ... other stuff
}

How to customize a URL to use a name different than my Controller?

I'm using ASP.NET MVC to develop a website and I need to customize my URL to use a name that is not the name of my Controller.
I want to use this Class/Method names:
public class CompanyController:Controller {
public ActionResult About() {
return View();
}
}
But I want to use the URL http://www.mysite.com/the-company/about-us to access my Controller/Method.
How should I proceed?
Thank you.
Since your question is mainly about controller naming I would (contrary to #Nissan Fan's answer) do at least this generalization, to make routing a bit more flexible and minimize the amount of routes, you'd have to define:
routes.MapRoute(
"CompanyRoute",
"the-company/{action}",
new { controller = "Company", action = "About" }
);
Your controller should of course be written this way:
public class CompanyController : Controller
{
[ActionName("about-us")]
public ActionResult About()
{
return View("About");
}
}
You will use URL Routing:
http://www.asp.net/learn/mvc/tutorial-05-cs.aspx
routes.MapRoute(
"AboutUs", // Route name
"the-company/about-us", // URL with parameters
new { controller = "CompanyController", action = "About" } // Parameter defaults
);

ASP.NET MVC Routing Question

I must be dense. After asking several questions on StackOverflow, I am still at a loss when it comes to grasping the new routing engine provided with ASP.NET MVC. I think I've narrowed down the problem to a very simple one, which, if solved, would probably allow me to solve the rest of my routing issues. So here it is:
How would you register a route to support a Twitter-like URL for user profiles?
www.twitter.com/username
Assume the need to also support:
the default {controller}/{action}/{id} route.
URLs like:
www.twitter.com/login
www.twitter.com/register
Is this possible?
What about
routes.MapRoute(
"Profiles",
"{userName}",
new { controller = "Profiles", action = "ShowUser" }
);
and then, in ProfilesController, there would be a function
public ActionResult ShowUser(string userName)
{
...
In the function, if no user with the specified userName is found, you should redirect to the default {controller}/{action}/{id} (here, it would be just {controller}) route.
Urls like www.twitter.com/login should be registered before that one.
routes.MapRoute(
"Login",
"Login",
new { controller = "Security", action = "Login" }
);
The important thing to understand is that the routes are matched in the order they are registered. So you would need to register the most specific route first, and the most general last, or all requests matching the general route would never reach the more specific route.
For your problem i would register routing rules for each of the special pages, like "register" and "login" before the username rule.
You could handle that in the home controller, but the controller method would not be very elegant. I'm guessing something like this might work (not tested):
routes.MapRoute(
"Root",
"{controller}/{view}",
new { controller = "Home", action = "Index", view = "" }
);
Then in your HomeController:
public ActionResult Index(string view) {
switch (view) {
case "":
return View();
case "register":
return View("Register");
default:
// load user profile view
}
}
OK I haven't ever properly tried this, but have you tried to extend the RouteBase class for dealing with users. The docs for RouteBase suggest that the method GetRouteData should return null if it doesn't match the current request. You could use this to check that the request matches one of the usernames you have.
You can add a RouteBase subclass using:
routes.Add(new UserRouteBase());
When you register the routes.
Might be worth investigating.
i think your question is similar to mine. ASP.NET MVC Routing
this is what robert harvey answered.
routes.MapRoute( _
"SearchRoute", _
"{id}", _
New With {.controller = "User", .action = "Profile", .id = ""} _
)
Here is an alternative way to standar route registration:
1. Download RiaLibrary.Web.dll and reference it in your ASP.NET MVC website project
2. Decoreate controller methods with the [Url] Attributes:
public SiteController : Controller
{
[Url("")]
public ActionResult Home()
{
return View();
}
[Url("about")]
public ActionResult AboutUs()
{
return View();
}
[Url("store/{?category}")]
public ActionResult Products(string category = null)
{
return View();
}
}
BTW, '?' sign in '{?category}' parameter means that it's optional. You won't need to specify this explicitly in route defaults, which is equals to this:
routes.MapRoute("Store", "store/{category}",
new { controller = "Store", action = "Home", category = UrlParameter.Optional });
3. Update Global.asax.cs file
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoutes(); // This do the trick
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
How to set defaults and constraints? Example:
public SiteController : Controller
{
[Url("admin/articles/edit/{id}", Constraints = #"id=\d+")]
public ActionResult ArticlesEdit(int id)
{
return View();
}
[Url("articles/{category}/{date}_{title}", Constraints =
"date=(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])")]
public ActionResult Article(string category, DateTime date, string title)
{
return View();
}
}
How to set ordering? Example:
[Url("forums/{?category}", Order = 2)]
public ActionResult Threads(string category)
{
return View();
}
[Url("forums/new", Order = 1)]
public ActionResult NewThread()
{
return View();
}

Resources