ASP.Net MVC Route issue - asp.net-mvc-3

I have an area called MyArea and it's registered like so:
context.MapRoute(null, "MyArea", new { controller = "MyAreaController", action = "Index" });
//Properties
context.MapRoute(null, "MyArea/properties", new { controller = "Property", action = "Index" });
context.MapRoute(null, "MyArea/properties/edit/{propertyId}", new { controller = "Property", action = "Property" });
//Units
context.MapRoute(null, "MyArea/properties/edit/{propertyId}/units/{unitId}", new { action = "Unit", propertyId = 1, unitId = 1 });
It should work that one property has many units, so I would like my url to look something like this:
http://localhost:50182/myarea/properties/edit/4/units/1
The code i use for the Html.ActionLink looks like:
#Html.ActionLink("Add new Unit", "Unit", "Unit", new { propertyId = 1, unitId = 1 })
I have an Unit controller with an action called Unit. Pleas help, what am i missing?
Thanks!!

You say "I have an Unit controller with an action called Unit. Pleas help, what am i missing?"
and your route mapping is currently ...
context.MapRoute(null, "MyArea/properties/edit/{propertyId}/units/{unitId}", new { action = "Unit", propertyId = 1, unitId = 1 });
How would you expect MVC to know what controller to use for that route? You need to specify controller = "Unit"
Update
Switch the order of
context.MapRoute(null, "MyArea/properties/edit/{propertyId}", new { controller = "Property", action = "Property" });
//Units
context.MapRoute(null, "MyArea/properties/edit/{propertyId}/units/{unitId}", new { action = "Unit", propertyId = 1, unitId = 1 });
in your route registration. Otherwise, something that should map to the second route will be intercepted by the first.

Related

Trouble with global.asax routing

I have some links in my webapp that looks like this:
localhost:12345/?something=1
localhost:12345/?something=2
localhost:12345/?something=3
localhost:12345/?something=4
each number at the end is an id that i need to pass to my controller to display information related to it.
I know I need to create a new routes.MapRoute in my global.asax page, but I am not really quite sure how to go about it. I tried this:
routes.MapRoute(
"Id", // Route name
"{controller}/{action}/{*Id}", // URL with parameters
new { controller = "Home", action = "Id", Id = "" } // Parameter defaults
);
---EDIT---
I am only successful getting each individual like to display by doing the following:
routes.MapRoute(
"IdRoute", // Route name
"{Id}", // URL with parameters
new { controller = "Home", action = "Index", id = 1 } // Parameter defaults
);
This does work, however, this only works for one id (specifically 1). I am not quite sure how to go about this, but i need i need:
localhost:12345/?something=1
to display the information for id 1,
localhost:12345/?something=2
to display the information for id 2,
localhost:12345/?something=3
to display the information for id 3.
I there are going to be hundreds of ids so hard coding something in would not be a convenient option. I have had no luck so far. Any help would be much appreciated! Thanks!
routes.MapRouteWithName(
"RootName",
"{id}",
new { controller = "Home", action = "Index", id = 1 });
This will produce links like this localhost/1
If you want this kind of links localhost/?id= 1
Then :
routes.MapRouteWithName(
"RootName",
String.Empty,
new { controller = "Home", action = "Index"});
public ActionResult Index(int id)
{
//do something with id, make query to database whatever
// u usually have model class so you would fill model with your data
var model = new YourModel();
//...
return View("Index", model);
}
If you have following Action in, say, HomeController:
public ActionResult SomeAction(int Id)
{
return View()
}
You may use any of following routes:
//* For Id = 3 this will return path "Home/SomeAction/3"
routes.MapRoute(
name: "First",
url: "{controller}/{action}/{Id}",
defaults: new { controller = "Home", action = "SomeAction", Id= UrlParameter.Optional}
);
//* For Id = 3 this will return path "SomeAction/3"
routes.MapRoute(
name: "First",
url: "{action}/{Id}",
defaults: new { controller = "Home", action = "SomeAction", Id= UrlParameter.Optional}
);
//* For Id = 3 this will return path "Home/SomeAction(3)"
routes.MapRoute(
name: "First",
url: "{controller}/{action}({Id})",
defaults: new { controller = "Home", action = "SomeAction", Id= UrlParameter.Optional}
);
//* For Id = 3 this will return path "LadyGaga/SomeAction/3"
routes.MapRoute(
name: "First",
url: "LadyGaga/{action}/{Id}",
defaults: new { controller = "Home", action = "SomeAction", Id= UrlParameter.Optional}
);

url parameters missing after adding a comment and redirecting back to blog post

I am teaching myself asp .net mvc3 by creating a blog application. However, I have
problems with comment upload. It is a very subtle error in that everything works when a user leaves a comment. However, the url of the post changes.
So, a blog post has a url
http://localhost:49175/Blog/Details/3/Third-post
This is generated by the url route map here:
routes.MapRoute(
"BlogDetail", // Route name
"Blog/Details/{id}/{urlHeader}", // URL with parameters
new { controller = "Blog", action = "Details", id = UrlParameter.Optional, urlHeader = UrlParameter.Optional } // Parameter defaults
);
Now, when a user leaves a comment - he is directed to a comment controller:
[HttpPost]
public ActionResult Create(BlogDetailsViewModels viewModel)
{
if (ModelState.IsValid)
{
try
{
blogrepository.Add(viewModel.Comment);
return RedirectToAction("Details", "Blog", new { id = viewModel.Comment.BlogID });
}
catch (DataException)
{
ModelState.AddModelError("", "Unable to save comment. Try again, and if the problem persits then contact administrator.");
}
}
// If we got this far, something failed, redisplay form
return RedirectToAction("Details", "Blog", new { id = viewModel.Comment.BlogID });
}
}
However, when somebody leaves a comment - he is redirected back to
http://localhost:49175/Blog/Details/3
I know, as of now there is nothing in the RedirectToAction that passes the urlHeader info. However, I have tried a few things like:
return RedirectToAction("Details", "Blog", new { id = viewModel.Comment.BlogID, urlHeader = viewModel.Blog.UrlHeader });
However, it doesn´t seem to work.
This is the blog details controller:
//
// GET: /Blog/Details/5
public ViewResult Details(int id, string urlHeader)
{
var blogs = blogrepository.GetBlog(id);
var recentblogs = blogrepository.FindRecentBlogs(5);
var archivelist = blogrepository.ArchiveList();
BlogDetailsViewModels viewModel = new BlogDetailsViewModels { Blog = blogs, RecentBlogs = recentblogs, ArchiveList = archivelist };
return View(viewModel);
}
I am stuck for days on this.
-- Full route method as requested --
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"BlogDetail", // Route name
"Blog/Details/{id}/{urlHeader}", // URL with parameters
new { controller = "Blog", action = "Details", id = UrlParameter.Optional, urlHeader = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"BlogArchive", // Route name
"Blog/{year}/{month}", // URL with parameters
new { controller = "Blog", action = "Archive" }, // Parameter defaults
new { year = #"\d{4}", month = #"\d{1,2}", } // Parameter constraints
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
If your form does not contains data for viewModel.Blog.UrlHeader, it will be an empty string, even viewModel.Blog may be null.
You can add a parameter to your post action method, like this:
[HttpPost]
public ActionResult Create(BlogDetailsViewModels viewModel, String urlHeader)
And, in your view that renders the form, use this code to generate the form element:
#Html.BeginForm("Create","Blog",new{urlHeader=Model.Blog.UrlHeader})
Alternatively, you can add a hidden input in your form for the urlHeader. In this way, you don't have to do any of previous two updates.
#Html.HiddenFor(m=>m.Blog.UrlHeader)
Either way, make sure your Model.Blog.UrlHeader is not null or an empty string

Value not getting passed in url

//In Controller this is what I have
public class AjaxController : Controller
{
[AcceptVerbs(new string[]{"GET"})]
public ActionResult FindRooms(string selectedBuilding)
{
return Json(new { Room = "x"}, JsonRequestBehavior.AllowGet);
}
}
//In Global.asax.cs I have
routes.MapRoute
(
"AjaxRoute1",
"Ajax/FindRooms/{selectedBuilding}",
new { controller = "Ajax", action = "FindRooms", selectedBuilding = "" }
);
If I browse to URL localhost/Ajax/FindRooms/SOMEBUILDING. The SOMEBUILDING is not getting passed to selectedBuilding parameter of FindRooms method. It is always null?? How can I fix this so that it works in both POST and GET?
As Mr TA suggested the other routes affects this. The order of routing is important.
I put the default route route at the end and works like a charm.!!
routes.MapRoute
(
"AjaxRoute1",
"Ajax/FindRooms/{selectedBuilding}",
new { controller = "Ajax", action = "FindRooms", selectedBuilding = "" }
);
routes.MapRoute
(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

Routing with areas and different parameters, misunderstanding

I have been confused all day, i have a routing in area and it looks like this.
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "admin";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRouteLowercase(null, "Account/{action}",
new {controller = "Account"},
new {action = #"LogOff|LogOn|Create|Update|Delete|List"},
new[] {"WebUI.Areas.Admin.Controllers"});
context.MapRouteLowercase( //this works
"AdminUpdateCategoryView",
"admin/{controller}/{action}/{cid}",
new {area = "admin", controller = "Main", action = "UpdateCategory", cid = ""},
new {cid = #"\d+"},
new[] {"WebUI.Areas.Admin.Controllers"}
);
context.MapRouteLowercase(//this not works
"AdminCategoryListView",
"admin/Main/{action}/{page}",
new { action = "Category", page = "1" },
new {page = #"\d+"},
new[] {"WebUI.Areas.Admin.Controllers"}
);
context.MapRouteLowercase(
"Admin_Default", // Route name
"admin/{controller}/{action}/{id}", // URL with parameters
new {controller = "Category", action = "Index", id = UrlParameter.Optional} // Parameter defaults
);
}
}
I have wrote what works and what not, but if change between them the one that doesn't work, works and the other that works, don't work?
example:
first case-> /admin/main/updatecategory/1 --> works
/admin/main/category/1 --> not works
result: /admin/main/category/1?page=1
second case-> /admin/main/category/1 --> works
/admin/main/updatecategory/1 --> not works
result: /admin/main/updatecategory/1?cid=1
Here is my controller actions:
public ActionResult Category(int? page)
{
int pageIndex = page.HasValue ? page.Value : 1;
return View("Category", CategoryViewModelFactory(pageIndex));
}
public ActionResult CreateCategory()
{
return View();
}
public ActionResult UpdateCategory(int cid)
{
return View();
}
public ActionResult DeleteCategory(int? cid)
{
return View();
}
What is this problem and how to solve it?
I'm totally confused, Routing in ASP.MVC3 is e-logical.
Help?!
When routes are searched, the first one that matches your URL is used. AdminUpdateCategoryView will match any admin controller, and action. You provide a default cid of "", but that shouldn't matter because you're requiring that cid be a number below that. AdminCategoryListView will match any url that enters main. Because you provide a default page of 1, it doesn't even matter if no page is provided.
So if AdminCategoryListView is on top: every single route in admin/main will use this route.
If AdminUpdateCategoryView is on top every route in admin that reaches this route and has a numerical cid value parameter will use it.
I'd recommend putting AdminCategoryListView on top because it's the more specific route. Either remove page="1" (depends on if you want to provide a default), or replace {action} with "category" so your other routes don't use this route. Also you should provide a default controller of main, otherwise it will assume the controller you're currently using is the correct one.
context.MapRouteLowercase(
"AdminCategoryListView",
"admin/Main/category/{page}",
new { action = "Category", controller = "Main" },
new {page = #"\d+"},
new[] {"WebUI.Areas.Admin.Controllers"}
);
//Put AdminUpdateCategoryView here

How to get url parameter from current route in asp.net mvc?

I have a route like this:
http://localhost/c/61/legetoj
its defined as:
routes.MapLocalizedRoute("Category",
"c/{categoryId}/{SeName}",
new { controller = "Catalog", action = "Category", SeName = UrlParameter.Optional },
new { categoryId = #"\d+" },
new[] { "Nop.Web.Controllers" });
Now, on all the pages having this url, I want to get SeName value (here is `legetoj')
In my view (header) I've tried this with: ViewContext.RouteData.Values["SeName"]
but it returns empty..
Do you know what I am doing wrong?
Just set up an action with the same name parameter as you would like to accept such as:
public ActionResult Category(int categoryId, string SeName) {
// do stuff
}
It should automatically insert that value inside the variable.

Resources