Asp.Net MVC Routing Passing Controller in Url - asp.net-mvc-4

I tried to write custom routes.Always i have 404 error what is wrong.I read about routing and did not figure out. I want to display contents like below codes and name must be between a-Z and 0-9.Thanks.
{action}/{name} /details/kll219dkl
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "home", action = "index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "test",
url: "details/{name}",
defaults: new { controller = "Test", action = "Details", name = "ujElk392ow" }
);
and just to showing is working
public ActionResult Details(string name)
{
return Content(name);
}

How about:
routes.MapRoute(
name: "test",
url: "{controller}/details/{name}",
defaults: new { controller = "Test", action = "Details", name = String.Empty },
constraints: new { name = #"^[a-zA-Z0-9]+$" }
);
Which would give you:
Url: Mapped Destination:
/Test/details/kll219dkl TextController->Details(name: "kll219dkl")

In addition to Brad answer. Try to change an order of your routes. Runtime takes first route which fits to request. So routes must be defined from most certain to most general. In your order runtime will always take default route.

Related

Area routing breaks in MVC6

In previous versions of ASP.NET, and using MVC 5, I could set up a route like this in my AreaRegistraion:
context.MapRoute(
"pfrecent",
"Forums/Recent/{page}",
new { controller = ForumController.Name, action = "Recent", page = 1 },
new[] { "PopForums.Controllers" });
This would route /Forums/Recent to the forum controller and its recent action. However, I can't figure out how to make it work in ASP.Net 5/MVC 6. I've added [Area("Forums")] to the controller class, and used this route from the Startup class:
routes.MapRoute(
"pfrecent",
"Forums/Recent/{page}",
new { controller = ForumController.Name, action = "Recent", page = 1 });
routes.MapRoute(
name: "areaRoute",
template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
However, it resolves to /Forums/Forum/Recent?page=1. The intention is to continue using /Forums/Recent.
We are using this for enabling areas in MVC 6:
// Configure MVC routing
app.UseMvc(routes =>
{
// Areas support
routes.MapRoute(
name: "areaRoute",
template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
// Default routing
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
The first route is for areas, second is for main content.
On Startup.cs
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
name: "Business",
template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
})
on Controller
[Area("Business")]
public class DemoController : Controller
{
public IActionResult Index()
{
return View();
}
}
Place this in your Startup.cs file at the TOP of the routes list:
routes.MapRoute(
name: "forumsAreaRoute",
template: "Forums/{action}/{page?}",
defaults: new {area = "Forums", controller = "Forum", action = "Recent", page = 1});
Your Forum controller should look like this:
[Area("Forums")]
public class ForumController : Controller
{
// GET: /<controller>/
public IActionResult Recent(int? page)
{
// Do action stuff here
}
}
This solution will satisfy a url of http://somedomain.com/Forums/Recent/1 and return the first page.
I hate answering my own questions, but after getting back to this, and looking at source and experimenting, I found that you have to specify the area in the route mapping, as well as the HtmlHelpers (I'm assuming this will be true for tag helpers as well, but I haven't gone that far yet in conversion.) So the route mapping has to look like this:
routes.MapRoute(
"pfrecent",
"Forums/Recent/{page?}",
new { controller = ForumController.Name, action = "Recent", page = 1, Area = "Forums" }
);
The important part is the Area property in the route value object. The HtmlHelper has to look like this, also naming the Area:
#Html.ActionLink(PopForums.Resources.Recent, "Recent", ForumController.Name, new { page = 1, Area = "Forums" }, null)
It causes the URL for the recent page to be /Forums/Recent as expected. As best I can tell, setting routes in a derived AreaRegistration class in MVC5 set the area value on the routes for you. Having [Area("Forums")] on your controller class (which I already had) seems to assume the previous role of area registration.

C# MVC4 Default Controller Redirect

I have two controllers: Default and Page. When the user hits the root http://localhost:1212 I want to redirect the user to Page Controller.
I used this code but no luck:
routes.MapRoute(
"Default",
"",
new { controller = "Page", action = "Get"}
);
Any ideas...?
Just change the original default in RouteConfig to look like this:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Page", action = "Index", id = UrlParameter.Optional }
);
Make sure that's the last entry if you're mapping other routes

supporting multi-tenant routes in mvc

I'm experimenting setting up a multi-tenant solution in asp.net mvc 4 wherein you are able to specify tenant specific overrides to certain controllers if they require different functionality.
I'd like to have routes that are like
/{Controller}/{Action}/{Id}/
/{Tenant}/{Controller}/{Action}/{Id}
If the tenant isn't specified it should just match the first route.
I have tried
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
routes.MapRoute(
name: "Tenant",
url: "{tenant}/{controller}/{action}/{id}",
defaults: new { tenant = "", controller = "Home", action = "Index", id = UrlParameter.Optional });
This works correctly for
/ -> detected as the first route (correct!)
/Home -> detected as
first route (correct!)
/Home/Index -> detected as first route
(correct!)
/Client1/Home/Index - Client1 is detected as controller
name (incorrect)
If I switch the routes around then the tenant route works but the base one does not.
What am I missing here, is it possible to achieve this?
Note, I'd prefer to not have to specify a dummy tenant string in the route as I'll have to translate that back later on in a few places where I need to resolve tenant specific information.
You can use the library I wrote here. This lib allows you to define an alternative route, if the routes conflict. You must define the routes as follows:
var firstRoute = routes.MapReplaceableRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
var secoundRoute = routes.MapRoute(
name: "Tenant",
url: "{tenant}/{controller}/{action}/{id}",
defaults: new { tenant = "", controller = "Home", action = "Index", id =
UrlParameter.Optional }, lookupParameters: new string[] {"tenant"}, lookupService: new LookupService());
firstRoute.AlternativeRoute = secondRoute;
For lookupService, you just need an empty implementation of the IRouteValueLookupService.

url.routerurl web api link for jquery ajax call

I'm trying to create a link to my WebApi controller using Url.RouterUrl, but I don't know how to add the controller action to it, this is what I have in my view:
var url = '#Url.RouteUrl("DefaultApi", new { httproute = "", controller = "ClientApi"})';
I want to add the FindClients action to the Url.RouterUrl, I have trying adding action=FindClients, but it produced this url /api/ClientApi?action=FindClients, I need my url to be /api/ClientApi/FindClients
Add the following key to App_Start\WebApiConfig.cs
config.Routes.MapHttpRoute(
name: "Extended",
routeTemplate: "api/{namespace}/{controller}/{action}/{id}",
defaults: new { }
);
As default route do not have {action}
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{namespace}/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Then use
#Url.RouteUrl("Extended", new { httproute = "", controller = "ClientApi"})

// GET: /Article/{text} in MVC?

I have a controller named ArticleController with an Index method that returns the Article view. This works.
However, I'd like to be able to process any text after Article/ in the URL such as Article/someText Article/fileNanme Article/etc
I thought this would be straightforward by implementing the following:
// GET: /Article/{text}
public ActionResult Index(string someText)
{
...
}
This doesn't work. Any ideas?
Update:
See routes:
routes.MapRoute(
name: "Articles",
url: "Article/{*articleName}",
defaults: new { controller = "Article", action = "Article", id= UrlParameter.Optional }
,
constraints: new { therest = #"\w+" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller="Home", action = "Index", id = UrlParameter.Optional }
);
See ArticleController methods:
public ActionResult Index()
{
...
}
public ActionResult Article(string articleName)
{
...
}
You can add a catch-all parameter to the route like this
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{*therest}",
defaults: new { controller = "Home", action = "Index" }
);
Notice the asterisk? This marks therest as a "catch-all" parameter, which will match all remaining segments in the URL.
In your action, you would have
public ActionResult Article(string therest)
{
/*...*/
}
This works even for URLs like "Home/Article/This/Is/The/Rest", in which case therest will have the value "This/Is/The/Rest".
If you want to leave out the controller part of the URL completely, you would have
routes.MapRoute(
name: "Default",
url: "Article/{*therest}",
defaults: new { controller = "Home", action = "Index" }
);
which will match URLs like "Article/ThisIs/JustSomeText".
If you want therest to at least contain something, you might add a routing constraint:
routes.MapRoute(
name: "Default",
url: "Article/{*therest}",
defaults: new { controller = "Home", action = "Index" },
constraints: new { therest = #"\w+" }
);
The constraint is a regular expression that therest must match for the route to match.
Stephen Walther has a nice article on routing and catch-all parameters.
Stephen Walther, again, has an article on routing constraints here.
If you are using standard routing change parameter name from someText to id. Otherwise you have to create custom routing for this parameter
You need to define a route in order to use the url you mentioned. For the latest MVC4, routes file exists in this directory App_Start/RouteConfig.cs
add this new route about the the default route.
routes.MapRoute(
name: "Custom",
url: "Article/{someText}",
defaults: new { controller = "Article", action = "Index" }
);
Try loading your url now. It should work now.