Reputation: 11329
Is there any way to pass arguments to controllers while defining the route table ?
so the same controller can be used for two or more "sections" e.g.
http://site.com/BizContacts // internal catid = 1 defined in the route
http://site.com/HomeContacts // internal catid = 3
http://site.com/OtherContacts // internal catid = 4
and the controller gets the custom argument defined in the route table to filter and display the data by that additional parameter
so in the example above the index action will be shown and the data shown will be returned by a query such as
select * from contacts where cat_id = {argument} // 1 or 3 or 4
i hope this is somewhat clear
any help is appreciated ?
Upvotes: 0
Views: 236
Reputation: 1038710
You could write a custom route:
public class MyRoute : Route
{
private readonly Dictionary<string, string> _slugs;
public MyRoute(IDictionary<string, string> slugs)
: base(
"{slug}",
new RouteValueDictionary(new
{
controller = "categories", action = "index"
}),
new RouteValueDictionary(GetDefaults(slugs)),
new MvcRouteHandler()
)
{
_slugs = new Dictionary<string, string>(
slugs,
StringComparer.OrdinalIgnoreCase
);
}
private static object GetDefaults(IDictionary<string, string> slugs)
{
return new { slug = string.Join("|", slugs.Keys) };
}
public override RouteData GetRouteData(HttpContextBase httpContext)
{
var rd = base.GetRouteData(httpContext);
if (rd == null)
{
return null;
}
var slug = rd.Values["slug"] as string;
if (!string.IsNullOrEmpty(slug))
{
string id;
if (_slugs.TryGetValue(slug, out id))
{
rd.Values["id"] = id;
}
}
return rd;
}
}
which could be registered in Application_Start
in global.asax
:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add(
"MyRoute",
new MyRoute(
new Dictionary<string, string>
{
{ "BizContacts", "1" },
{ "HomeContacts", "3" },
{ "OtherContacts", "4" },
}
)
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
and finally you could have your CategoriesController:
public class CategoriesController : Controller
{
public ActionResult Index(string id)
{
...
}
}
Now:
http://localhost:7060/bizcontacts
will hit the Index
action of Categories
controller and pass id=1http://localhost:7060/homecontacts
will hit the Index
action of Categories
controller and pass id=3http://localhost:7060/othercontacts
will hit the Index
action of Categories
controller and pass id=4Upvotes: 1