Area routes being ignored? - asp.net

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}

Related

How to send string id to controller using actionlink

i am tring to have links link this
/View/test
it is working only if it is int like /View/1
my view action link
#Html.ActionLink(item.className, "Viewe", "subject", new {id =item.className },null)
my control action
public ViewResult Viewe(string id)
{
//some database
return View();
}
i get this error Server Error in '/' Application.
if i change the id into anything it works fine but the link will looks like
this : View?anything=par
image of the error
route code
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
this is working for me
#Html.ActionLink(item.ClassName, "Viewe", "Subject", new { Id = item.ClassName }, null)

Getting an Actionresult Parameter in MVC4

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.

RedirectToAction() generates wrong URL

I'm having a problem with MVC 4, and I guess it's something really trivial, but it's been bugging me for the last day and I can't seem to figure it out.
I have this url:
http://www.example.com/my-dashed-url
I have a Controller named:
public class MyDashedUrlController: Controller
{
}
I have only two Routes like this:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("my-dashed-url",
"my-dashed-url/{action}",
new { controller = "MyDashedUrl", action = "Index" });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home",
action = "Index",
id = UrlParameter.Optional }
);
I get to the index just fine. However, when I do this:
public ActionResult Index()
{
if (NoUserIsLoggedOn)
return RedirectToAction("Logon", "MyDashedUrl");
return View();
}
public ActionResult Logon()
{
Contact c = GetContact();
return View(c);
}
It doesn't redirect me to the "Logon" action properly.
It should redirect me to:
http://www.example.com/my-dashed-url/logon
but instead it tries to redirect me to:
http://www.example.com/logon
... which doesn't work (404 Not Found)
I'm missing something. Can anyone spot it? If anyone needs any more information, let me know.
And it's EVERY RedirectToAction that does the same thing in this controller. A Html.BeginForm("Logon", "MyDashedUrl") would also generate:
http://www.example.com/logon
I guess it has to do something with the Routes I defined, but I can't find the faulty one, seeing as they're all the same. If I disable all of my Routes besides the default one from MVC, the problem remains the same
Make sure that you have declared this custom route BEFORE the default one:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"my-dashed-url",
"my-dashed-url/{action}",
new { controller = "MyDashedUrl", action = "Index" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
Remember that routes are evaluated in the order you declared them. So the first route that matches a request will be used. If you declare your custom route after the default one, it is the default route that will match the request.

ASP.NET MVC3 Route - example.com/blog/projects to example.com/projects

I have an ActionResult in my Blog controller that is returning all the projects called Projects, but my URL looks like example.com/blog/projects, I want to set up route to make it look like example.com/projects.
Is it possible? And if it is then how can I achieve that?
You have to register route following way Global.asax and put this as a first route
routes.MapRoute("Projects", "Projects" , new { controller="blog" , action="Projects" });
You can add a route to your Global.asax.cs file, such as:
routes.MapRoute(
"Projects", // Route name
"Projects/{id}", // URL with parameters
new { controller = "Blog", action = "Projects", id = UrlParameter.Optional } // Parameter defaults
);
So it looks something like this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Projects", // Route name
"Projects/{id}", // URL with parameters
new { controller = "Blog", action = "Projects", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
Make sure you put your new route above the default one otherwise yours will never be hit.

ASP.NET MVC catch-all routing

I have read a few threads on StackOverflow about this, but cannot get it to work. I have this at the end of my RegisterRoutes in Global.asax.
routes.MapRoute(
"Profile",
"{*url}",
new { controller = "Profile", action = "Index" }
);
Basically what I'm trying to achieve is to have mydomain.com/Username point to my member profilepage. How would I have to set up my controller and RegisterRoutes in order for this to work?
Currently mydomain.com/somethingthatisnotacontrollername gets a 404-error.
Solution that works for your case but is not recommended
You have a predefined set of controllers (usually less than 10) in your application so you can put a constraint on controller name and then route everything else to user profile:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new { controller = "Home|Admin|Reports|..." }
);
routes.MapRoute(
"Profile",
"{username}/{action}",
new { controller = "Profile", action = "Details" }
);
But this will not work in case some username is the same as your controller name. It's a small possibility based on experience end empirical data, but it's not 0% chance. When username is the same as some controller it automatically means it will get handled by the first route because constraints won't fail it.
Recommended solution
The best way would be to rather have URL requests as:
www.mydomain.com/profile/username
Why do I recommend it to be this way? Becasue this will make it much simpler and cleaner and will allow to have several different profile pages:
details www.mydomain.com/profile/username
settings www.mydomain.com/profile/username/settings
messages www.mydomain.com/profile/username/messages
etc.
Route definition in this case would be like this:
routes.MapRoute(
"Profile",
"Profile/{username}/{action}",
new { controller = "Profile", action = "Details" }
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
having something that matches to mydomain.com/Username isn't really going to work because there is no way for the routing engine to distinguish between
mydomain.com/someusername
and
mydomain.com/controllername
What might be possible is, if your username scheme has a unique set of properties, i.e. is a sequence of 9 digits, you could define a route to check for something that looks like a username.
routes.MapRoute("",
"UserRoute",
"{username}",
new { controller = "Profile", action = "Index"},
new { {"username", #"\d{9}"}}
);
The key point tho, is that you need to provide some way for the routing engine to differentiate between a username and a standard controller action
You can find out more about constraints here
I had a requirement like this for my project. What i did was creating a route constraint like below:
public class SeoRouteConstraint : IRouteConstraint
{
public static HybridDictionary CacheRegex = new HybridDictionary();
private readonly string _matchPattern = String.Empty;
private readonly string _mustNotMatchPattern;
public SeoRouteConstraint(string matchPattern, string mustNotMatchPattern)
{
if (!string.IsNullOrEmpty(matchPattern))
{
_matchPattern = matchPattern.ToLower();
if (!CacheRegex.Contains(_matchPattern))
{
CacheRegex.Add(_matchPattern, new Regex(_matchPattern));
}
}
if (!string.IsNullOrEmpty(mustNotMatchPattern))
{
_mustNotMatchPattern = mustNotMatchPattern.ToLower();
if (!CacheRegex.Contains(_mustNotMatchPattern))
{
CacheRegex.Add(_mustNotMatchPattern, new Regex(_mustNotMatchPattern));
}
}
}
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
var matchReg = string.IsNullOrEmpty(_matchPattern) ? null : (Regex)CacheRegex[_matchPattern];
var notMatchReg = string.IsNullOrEmpty(_mustNotMatchPattern) ? null : (Regex)CacheRegex[_mustNotMatchPattern];
var paramValue = values[parameterName].ToString().ToLower();
return IsMatch(matchReg, paramValue) && !IsMatch(notMatchReg, paramValue);
}
private static bool IsMatch(Regex reg, string str)
{
return reg == null || reg.IsMatch(str);
}
}
Then in the register route method:
routes.MapRoute("",
"UserRoute",
"{username}",
new { controller = "Profile", action = "Index"},
new { username = new SeoRouteConstraint(#"\d{9}", GetAllControllersName())}
);
The method GetAllControllersName will return all the controller name in your project separated by | :
private static string _controllerNames;
private static string GetAllControllersName()
{
if (string.IsNullOrEmpty(_controllerNames))
{
var controllerNames = Assembly.GetAssembly(typeof(BaseController)).GetTypes().Where(x => typeof(Controller).IsAssignableFrom(x)).Select(x => x.Name.Replace("Controller", ""));
_controllerNames = string.Join("|", controllerNames);
}
return _controllerNames;
}

Resources