How should i make this ASP.NET MVC Route? - asp.net-mvc

i wish to have the following url(s).. and i'm not sure how i should do the following:
1) Route registered in the global.asax
2) Controller method
Urls/Routes
- http://www.mysite.com/
- http://www.mysite.com/?page=2
- http://www.mysite.com/?tags=fooBar
- http://www.mysite.com/?page=2&tags=fooBar
Please note - i do not want to have http://www.mysite.com/{page}/{tags}/ etc.. if that difference makes sence. I also understand about the default routes, but i'm not sure how to tweak them to make it do what i require.
Lastly, i also know how to use Html.ActionLink(..) so I'm not worried about how to use that.
any suggestions?
Unit Testing
I'm also under the impression that i could do a unit test, like the following:-
(using MvcFakes)...
// Arrange.
var routes = new RouteCollection();
MvcApplication.RegisterRoutes(routes);
// Act.
context = new FakeHttpContext("~/?page=2&tags=fooBar");
routeData = routes.GetRouteData(context);
// Assert.
Assert.AreEqual("Home", routeData.Values["controller"]);
Assert.AreEqual("Index", routeData.Values["action"]);
Assert.AreEqual(2, routeData.Values["page"]);
Assert.AreEqual("fooBar", routeData.Values["tags"]);
Update 1
I'm hoping to run all these of the Index action on the default HomeController, if this helps. (in actual fact, I've renamed my HomeController to PostController but that is not really important / shouldn't effect the problem).

Actually for what you are trying to do you don't need additional route. The default MVC route handles your request well. You just have to keep in mind that controller action parameter names must match your url param names.
URL: http://www.mysite.com/?page=2&tags=fooBar
public ActionResult Index(string page, string tags)
{
ViewData["Message"] = string.Format("Page={0}, Tags={1}", page, tags);
return View();
}
Of course thats for Controller "Home" and Action "Index" as defaults. But the point is clear I hope.
Scott Guthrie has excellent post about routing Here

Related

ASP.NET MVC Dynamic Action with Hyphens

I am working on an ASP.NET MVC project. I need to be able to map a route such as this:
http://www.mysite.com/Products/Tennis-Shoes
Where the "Action" part of the URL (Tennis-Shoes") could be one of a list of possibilities. I do not want to have to create a separate Action method in my controller for each. I want to map them all to one Action method and I will handle the View that is displayed from there.
I have this working fine by adding a route mapping. However, there are some "Actions" that will need to have a hyphen in them. ASP.NET MVC routing is trying to parse that hyphen before I can send it to my action. I have tried to create my own custom Route Handler, but it's never even called. Once I had a hyphen, all routes are ignored, even my custom one.
Any suggestions? Details about the hyphen situation? Thanks you.
Looking at the URL and reading your description, Tennis-Shoes in your example doesn't sound like it should be an action, but a Route parameter. Let's say we have the following controller
public class ProductsController : Controller
{
public ActionResult Details(string product)
{
// do something interesting based on product...
return View(product);
}
}
The Details action is going to handle any URLs along the lines of
http://www.mysite.com/Products/{product}
using the following route
routes.MapRoute(
null,
"Products/{product}",
new
{
controller = "Products",
action = "Details"
});
You might decide to use a different View based on the product string, but this is just a basic example.

MVC 3 Route question

I'm trying to put in some new routes but not sure where to start. What I would like to do is to have my routes translate as follows:
/transport class A/23 translated to /info/classes/A-23
I understand the basics of using MapRoute but can I do things like the above?
I hope someone can give advice.
This seems to me that you're actually after something like UrlRewrite since you're going from one Url to another.
But MVC doesn't rewrite Urls - it maps them to controller actions based on route patterns you provide.
So, if you're asking if you can split up the first url to a controller/action pair (with parameters) then of course you can. You just set up a route with the necessary parameters in the right place. So you could call MapRoute with something like (I would use hyphens for the spaces):
/*route pattern:*/ "transport-class-{class1}/{class2}"
/*with route defaults:*/ new { controller = "Info", action = "ViewInfo" }
Then you could write a controller as follows:
public class InfoController : ControllerBase
{
public ActionResult ViewInfo(string class1, string class2)
{
//presumably get model data from the class parameters here
//and pass it as parameter to below:
return View();
}
}
Although it would depend also if the transport and class constants in this route are actually also variable I guess - in which case you could push those down as route parameters, and into the parameter list of your controller method.

ASP.Net MVC redirecttoaction not passing action name in url

I have a simple create action to receive post form data, save to db and redirect to list view.
The problem is, after redirecttoaction result excutes, the url on my browser lost the action section. Which it should be "http://{hotsname}/Product/List" but comes out as "http://{hotsname}/Product/".
Below is my code:
[HttpPost]
public ActionResult Create(VEmployee model, FormCollection fc)
{
var facility = FacilityFactory.GetEmployeeFacility();
var avatar = Request.Files["Avatar"].InputStream;
var newModel = facility.Save(model, avatar);
return RedirectToAction("List");
}
The page can correctly render list view content, but since some links in this view page use relative url, the functions are interrupted. I am now using return Redirect("/Employee/List") to force the url. But I just wonder why the action name is missing. I use MVC3 and .Net framwork 4.
I am new to ASP.Net MVC, thanks for help.
Your route table definitely says that "List" action is default, so when you redirect to it as RedirectToAction("List") - routing ommits the action because it is default.
Now if you remove the default value from your routes - RedirectToAction will produce a correct (for your case) Url, but you'll have to double check elsewhere that you are not relying on List being a default action.
Well, Chris,
If you get the right content on http://{hotsname}/Product/ then it seems that routing make that URL point to List either indirectly (using pattern like {controller}/{action}) and something wrong happens when resolving URL from route or {action} parameter is just set wth default value List. Both URLs can point to the same action but the routing engine somehow takes the route without explicit action name.
You should check:
Order in which you define your routes
How many routes can possibly lead to EmployeeController.List()
Which one of those routes has the most priority
Default values for your routes
Just make the route with explicit values: employee/list to point to your List action and make sure that is the route to select when generating links (it should be most specific route if possible).
It would be nice if you provide your routes mappings here.
but since some links in this view
page use relative url, the functions
are interrupted.
Why do you make it that way? Why not generate all the links through routing engine?
When using the overload RedirectToAction("Action") you need to be specifying an action that is in the same controller. Since you are calling an action in a different controller, you need to specify the action with the alternate overload e.g. RedirectToAction("List", "Employee").

asp.net mvc routing question

the default routing works fine
mysite.com/home/about
and i even see how to customize it to make it shorter
so i can say:
mysite.com/edit/1
instead of
mysite.com/home/edit/1
but how can i make it longer to handle url like the following
mysite.com/admin/user/1 // works
mysite.com/admin/user/details // does not work
mysite.com/admin/question/create // does not work
i cant just treat the id as an action? i need a custom route?
do i need to create new controllers for each table or can i route them all through the Admin controller
thanks a lot
As has been mentioned already, probably your best bet would be to use the new Areas feature
You can achieve this type of routing without Areas, but as the number of controllers gets large the maintainability of your site will diminish. Essentially what you do is to hard-code the controller name into the Route definition which means that you have to add new route mappings for each new Admin controller. Here's a few examples of how you might want to set up your routes without Areas.
routes.MapRoute("AdminQuestions", // Route name
"admin/question/{action}/{id}", // URL with parameters
new { controller = "AdminQuestion", action = "Index" } // Parameter defaults
);
routes.MapRoute("AdminUsers", // Route name
"admin/user/{action}/{id}", // URL with parameters
new { controller = "AdminUser", action = "Index" } // Parameter defaults
);
Alternatively you could route everything through the Admin controller, but it would quickly become very messy with your controller actions performing multiple roles.
routes.MapRoute("Admin", // Route name
"admin/{action}/{type}/{id}", // URL with parameters
new { controller = "Admin", action = "Index" } // Parameter defaults
);
With your AdminController action(s) looking like:
public virtual ActionResult Create(string type, int id)
{
switch (type)
{
case 'question':
// switch/case is code smell
break;
case 'user':
// switch/case is code smell
break;
// etc
}
}
Adding routes to global.asax is fairly straight forward. Put the more specific routes above the more general routes. The most typical pattern is controller/action/parameter/parameter... If you need something more complex, you may want to look at MVC Areas.In you example above "mysite.com/admin/user/details" is looking for a controller named "admin" and an action named "user", with everything after that being parameter on the action method (assuming a typical route setup)

URLs the asp.net mvc way

In the conventional website a url displayed as:
http://www.mySite.com/Topics
would typically mean a page sits in a subfolder below root named 'Topics' and have a page named default.htm (or similar).
I'm trying to get my head in gear with the MVC way of doing things and understand just enough of routing to know i should be thinking of URLs differently.
So if i have a db-driven page that i'd typically script in a physical page located at /Topics/index.aspx - how does this look in an MVC app?
mny thx
--steve...
It sounds like you are used to breaking down your website in terms of resources(topics, users etc) to structure your site. This is good, because now you can more or less think in terms of controllers rather than folders.
Let's say you have a structure like this in WebForms ASP.NET.
-Topics
-index.aspx
-newtopic.aspx
-topicdetails.aspx
-Users
-index.aspx
-newuser.aspx
-userdetails.aspx
The structure in an MVC app will be pretty much the same from a users point of view, but instead of mapping a url to a folder, you map a url to a controller. Instead of the folder(resource) having files inside it, it has actions.
-TopicController
-index
-new
-details
-UserController
-index
-new
-details
Each one of these Actions will then decide what view (be this html, or json/xml) needs to be returned to the browser.
Actions can act differently depending on what HTTP verb they're repsonding to. For example;
public class UserController : Controller
{
public ActionResult Create()
{
return View(new User());
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(User user)
{
// code to validate /save user
if (notValid)
return new View(user);
else
return new View("UserCreatedConfirmation");
}
}
This is sort of a boiled down version of RESTful URLs, which I recommend you take a look at. They can help simplify the design of your application.
It looks just like you want it to be.
Routing enables URL to be quite virtual. In asp.net mvc it will end at specified controller action method which will decide what to do further (i.e. - it can return specified view wherever it's physical location is, it can return plain text, it can return something serialized in JSON/XML).
Here are some external links:
URL routing introduction by ScottGu
ASP.NET MVC tutorials by Stephan Walther
You would have an default view that is associated with an action on the Topics controller.
For example, a list page (list.aspx) with the other views that is tied to the list action of the Topics controller.
That is assuming the default routing engine rules, which you can change.
Read more here:
http://weblogs.asp.net/scottgu/archive/2007/12/03/asp-net-mvc-framework-part-2-url-routing.aspx
IMHO this is what you need for your routes.
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Topics", action = "Index", id = "" } // Parameter defaults
);
You would need a TopicsController that you build the View (topics) on.

Resources