Getting an Actionresult Parameter in MVC4 - asp.net

I'm working on a simple MVC application, where I am generating below path
#Html.ActionLink(#objcity.CityName, "AgentProfiles", "Home", new {#Id=objcity.MaProvision.ProvinceName+"/"+#objcity.CityName }, null)
It makes a url like this:
http://localhost:45896/Home/AgentProfiles/Ontario/testt
In the controller I have written this method:
public ActionResult AgentProfiles(String Id)
{
//Code
}
Is it possible to get in /Ontario/testt in Id variable?

You want to get /Ontario/testt in Id(route parameter) for this you have to modify your default routes little bit or you have to make a custom route but in my opinion for your simple requirement try below answer.
Instead of
#Html.ActionLink(#objcity.CityName, "AgentProfiles", "Home", new {#Id=objcity.MaProvision.ProvinceName+"/"+#objcity.CityName }, null)
Modify Actionlink this way
#Html.ActionLink(#objcity.CityName, "AgentProfiles", "Home", new { ProvinceName=objcity.MaProvision.ProvinceName ,CityName = objcity.CityName }, null)
Controller Action :
public ActionResult AgentProfiles(string ProvinceName,string CityName ) //get ProvinceName and CityName which will be coming as querystring variables as shown here.
{......}
OR
EDIT :- Try this as per your comment.
Add one more route in RouteConfig.cs file inside AppStart folder as shown below :
routes.MapRoute(
"MvcRoutes", // Route name
"{controller}/{action}/{provincename}/{cityname}", // URL with parameters
new { controller = "Home", action = "Index", provincename = "", cityname= "" } // Parameter defaults
);
Don't forget to put this custom route above default route.
Modify ActionLink as shown below :
#Html.ActionLink(#objcity.CityName, "AgentProfiles", "Home", new { provincename = objcity.MaProvision.ProvinceName , cityname = objcity.CityName }, null)
Controller Action :
public ActionResult AgentProfiles(string provincename ,string cityname)
{......}

you can modify your routing like-
{controller}/{action}/{*catchall}
and in action method
public ActionResult AgentProfiles(string catchall)
{
// your code
}
Then you will have value /Ontario/testt in your catchall parameter which you can use in action method.

Related

asp.net route does not work

I have a next route:
routes.MapRoute(
"CatalogFilter",
"{url}Catalog.aspx/{fltr}",
new { controller = "Catalog", action = "Index", page = 1 }
);
So link does not match that route: http://localhost:63515/MotorOilCatalog.aspx?fltr=156 instead of http://localhost:63515/MotorOilCatalog.aspx/156.
I tried to remove all other routes to be sure that there are no unambiguous or conflicted routes but it also does not work.
I installed Phil Haacks "Route Debugger" and it shows:
To build a link that matches this route:
routes.MapRoute(
"CatalogFilter",
"{url}Catalog.aspx/{fltr}",
new { controller = "Catalog", action = "Index", page = 1 }
);
You need to specify all of the route values that exist in the route. You have 5 values:
controller
action
page
url
fltr
So you need to supply all 5 values to match the route from an ActionLink. If you want to generate the URL /MotorOilCatalog.aspx/156, you have to make the ActionLink like this:
#Html.ActionLink("my link", "Index", "Catalog", new { page = 1, fltr = 156, url = "MotorOil" }, null)
Do note that the way you have it configured, the only way to override a page number from the URL is to add it to the query string.
/MotorOilCatalog.aspx/156?page=2
Since your question is unclear, I am assuming of course that this is an MVC application, and that you have a Catalog controller in your application with an Index method.
public class CatalogController : Controller
public ActionResult Index(string url, int fltr, int page)
{
// Implementation
return View();
}
}
If this is in fact an ASP.NET application, you should be using MapPageRoute instead of MapRoute to build your routes to map them to physical pages instead of controllers.
Reference: https://msdn.microsoft.com/en-us/library/cc668177.aspx

MVC 3 Routes: Dynamic content from home controller - Where am I going wrong?

My Setup
I have a set of controllers in the normal fashion, which have their usual CRUD action methods inside them. Examples of these controllers are Testimonials, Galleries, and FAQs. These have backing models in Entity Framework, such as Testimonial, Gallery and FAQ, respectively.
You get to these by this sort of URL: /Galleries/Edit/2
All good so far, and all by default conventions...
I also have a set of pages that need to have editable content in them, and these have their content populated from a database via Entity Framework. They use an EF model behind them called "Page". This has a content property (html), and a name property so that I can match the incoming request. These pages are the Home, About and Prices pages.
I have chosen the Home controller to do this - I intend to have the index Action work out which Page to load from the DB by a name parameter:
[AllowAnonymous]
public ActionResult Index(string name = "Home")
{
// look up the page by name in the DB.
var model = context.Pages.FirstOrDefault(p => p.Title == name);
// trap errors.
if (model == null)
{
return RedirectToAction("NotFound", "Error", new { aspxerrorpath = name } );
}
// normal path
return View(model);
}
So, I could in theory add new items to the Pages table/DbSet and these would get mapped properly to this controller and action. I will then add an edit action for admin to edit the content that has the same signature as the index action above.
The Problem
The issue comes with Routing requests...
I had 2 initial routes:
routes.MapRoute("DynamicAccess",
"{name}/{action}",
new { controller = "Home", action = "Index" });
routes.MapRoute("Default",
"{controller}/{action}/{id}",
new { controller = "Home", action="Index", id=UrlParameter.Optional});
This fails when I go to "Galleries/", as it goes through the Home controller each time, and fails if I swap them around. I was also getting requests for Scripts/ folder through to the home controller too....
My Temporary Solution
My current routes now look like this:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("favicon.ico");
routes.MapRoute("Gallery",
"Gallery/{action}/{id}",
new { controller = "Galleries", action = "Index", id = UrlParameter.Optional });
routes.MapRoute("Testimonials",
"Testimonials/{action}/{id}",
new { controller = "Testimonials", action = "Index", id = UrlParameter.Optional });
routes.MapRoute("FAQs",
"FAQs/{action}/{id}",
new { controller = "FAQs", action = "Index", id = UrlParameter.Optional });
routes.MapRoute("DynamicAccess",
"{name}/{action}",
new { controller = "Home", action = "Index" });
routes.MapRoute("Default",
"{controller}/{action}/{id}",
new { controller = "Home", action="Index", id=UrlParameter.Optional});
routes.MapRoute("Root",
"",
new { controller = "Home", action = "Index" });
routes.MapRoute("AdminAccess",
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { authenticated = new AuthenticatedAdminRouteConstraint() });
You can see here that I've had to declare a route for each of my static pages above the route for the dynamically resolved Home Route.
Question
This looks clumsy to me - having to add each non-dynamic page to my routes table.
Can anyone point me to a cleaner way of doing this please?
Thanks in advance.
Why not put a constraint on your static routes, which will allow routes that don't match to fall through to the dynamic route?
routes.MapRoute("default",
"{controller}/{action}/{id}",
new {controller="home", action="index", id=UrlParameter.Optional},
new {controller="^(|home|gallery|testimonial|faq)$"});
routes.MapRoute("dynamic",
"{name}/{action}",
new {controller="home", action="index"});
You will have to change your controllers to match the singular name in the constraint but other than that, it ought to work.

Area routes being ignored?

I have these routes:
routes.MapRoute(
"Advertisers",
"advertisers/{controller}/{action}/{id}",
new { controller = "Index", action = "Index", id = UrlParameter.Optional },
new string[] { "Portal.Areas.Advertisers.Controllers" }
);
routes.MapRoute(
"Root", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Index", action = "Index", id = UrlParameter.Optional }, // Parameter defaultsm
new string[] { "Portal.Controllers" }
);
However whenever I go to /advertisers/controller/action/id it is not reading the id parameter... what am I doing wrong?
Thanks
I'd suggest you take a look at the Route Debugger
nuget install
PM> Install-Package routedebugger
After you've installed it into your project, put this one line of code inside your application start method, and hit the url you're debugging.
protected void Application_Start()
{
RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);
}
This will tell you exactly why your routes aren't working as expected.
As for your actual question, is your Controller actually called IndexController? Because this doesn't seem right to me
public class IndexController : Controller
{
public ActionResult Index()
{
return View();
}
}
My assumption is that you actually have something like HomeController or AdvertiserController, and if that's the case you should have something like this
routes.MapRoute(
"advertisers_default", // Route name
"advertisers/{controller}/{action}/{id}/{advertiserName}", // URL with parameters
new { controller = "Home",
action = "Index",
advertiserName = UrlParameter.Optional },
new { id = "[0-9]+",
controller = "[a-zA-Z]+",
action = "[a-zA-Z]+" }
);
and then hit the url http://example.com/advertisers/{id}/{advertiser-name}
Simply said, this url looks wrong to me
/advertisers/controller/action/{id}
it should be
/advertisers/home/{id}
or even
/advertisers/home/{id}/{advertiser-name}

Html.ActionLink showing query url instead of pretty url

The Html.ActionLink
<li> ${Html.ActionLink<HomeController>(c => c.Edit(ViewData.Model.Id, ViewData.Model.Title), "Edit")} </li>
When created as html shows the URL to be Edit/5006?title=One . How do I change this to a pretty URL like Edit/5006/One ?
My Edit Action method is
public ActionResult Edit(int id, string title)
You need to have a route setup:
routes.MapRoute(
"DefaultWithTitle",
"{controller}/{action}/{id}/{title}",
new
{
controller = "Home",
action = "Edit",
id = UrlParameter.Optional,
title = UrlParameter.Optional
}
);
It is not depends on the function stamp, but it depends on the routing configuration.
routes.MapRoute("Edit", // Route name
"{controller}/{action}/{id}/{title}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
Take a look at the first answer to this question: HTML.ActionLink method
The important point is that you have to make sure you're using the right overload for ActionLink().

ASP.NET MVC SEO URL

My goal is to have the url routing as following:
http://www.abc.com/this-is-peter-page
http://www.abc.com/this-is-john-page
What is the simplest way to achieve this without placing controller name an function name in the url above? If page above not found, I should redirect to 404 page.
Addon 1: this-is-peter-page and this-is-john-page is not static content, but is from database.
Similar to KingNestor's implementation, you can also do the followings which will ease your work:
1) Write Your Model
public class MyUser{public String UserName{get; set;}}
2) add route to global asax
routes.MapRoute(
"NameRouting",
"{name}",
new { controller = "PersonalPage", action = "Index", username="name" });
3) Roll your own custom model binder derived from IModelBinder
public class CustomBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var request = controllerContext.HttpContext.Request;
var username = getUserNameFromDashedString(request["username"]);
MyUser user = new MyUser(username);
return user;
}
}
4) in your action:
public ActionResult Index([ModelBinder(typeof(CustomBinder))] MyUser usr)
{
ViewData["Welcome"] = "Viewing " + usr.Username;
return View();
}
I personally wouldn't suggest a route like that but if it meets your needs you need to do something like:
Have the following route in your Global.asax file:
routes.MapRoute(
"NameRouting",
"{name}",
new { controller = "PersonalPage", action = "routeByName" });
Then, in your "PersonalPageController", have the following method:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult routeByName(string name)
{
switch (name)
{
case "this-is-peter-page": return View("PeterView");
case "this-is-john-page": return View("JohnView");
case Default: return View("NotFound");
}
}
Make sure you have the appropriate views: "PeterView", "JohnView" and "NotFound" in your Views/PersonalPage/.
I don't think this can be done. AFAIK ASP.NET MVC recognizes routing parameters via the character "/".
Your format, on the other hand, goes by "{controller}-is-{id}-{action}" -- so there is no way the controller can be distinguished from the id and the action.
I think using "/" characters doesn't affect or degrade SEO; it only affects human readability and retention of the URL.
Anyway, the following URL is possible: http://www.abc.com/this-is-the-page-of/Peter by adding another route in the Global.asax RegisterRoutes method:
routes.MapRoute(
"AnotherRoute",
"this-is-the-page-of/{id}",
new { controller = "PersonalPage", action = "Details", id = "" }
);
...assuming that PersonalPageController implements a Details ActionResult method that points to the desired page.

Resources