asp.net mvc - How to make one controller the default one when only action specified? -
i using standard mvc template mvc 2013.
there home
controller actions about, contact, etc.
there account
controller actions login, logout, etc.
the app deployed @ domain website
. url http://website produce output of /home/index, without changing url in browser address box, ie browser shows not result of http redirect.
how make url http://website/x route /home/x if x not controller in application? otherwise should route /home/x/index.
the reason http://website/about, http://website/contact etc without home.
a naive solution define new route above default (catch-all) looks like:
routes.maproute( name: "shorturltohomeactions", url: "{action}", defaults: new { controller = "home" } );
the problem approach prevent accessing index
(default action) of other controllers (requesting /other
, when have othercontoller
index
action result in 404, requesting /other/index
work).
a better solution create routeconstraint
match our /{action}
in case there no other controller same name:
public class noconflictingcontrollerexists : irouteconstraint { private static readonly dictionary<string, bool> _cache = new dictionary<string, bool>(stringcomparer.ordinalignorecase); public bool match(httpcontextbase httpcontext, route route, string parametername, routevaluedictionary values, routedirection routedirection) { var path = httpcontext.request.path; if (path == "/" || string.isnullorempty(path)) return false; if (_cache.containskey(path)) return _cache[path]; icontroller ctrl; try { var ctrlfactory = controllerbuilder.current.getcontrollerfactory(); ctrl = ctrlfactory.createcontroller(httpcontext.request.requestcontext, values["action"] string); } catch { _cache.add(path, true); return true; } var res = ctrl == null; _cache.add(path, res); return res; } }
then applying constraint:
routes.maproute( name: "shorturltohomeactions", url: "{action}", defaults: new { controller = "home" }, constraints: new { noconflictingcontrollerexists = new noconflictingcontrollerexists() } );
see msdn
Comments
Post a Comment