I have only 1 controller and have 1 action only in my example like this:
//
// GET: /Home/
public ActionResult Index(string source,string id)
{
return View();
}
I have 2 routes registered for this action like -:
routes.MapRoute(
name: "Default2",
url: "{source}/{id}",
defaults: new { controller = "Home", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "",
defaults: new { controller = "Home", action = "Index", source="source1", id = UrlParameter.Optional }
);
When I call default, it calls Index action, which is OK
when I call like this, /source1/12 - it works.
But when I call like this /source1/12.0 - it does not work and shows up 404 ..
Can anyone suggest why is this happening ?
It's probably interpreting the .0 as a file extension, and thus looking for a file on disk. Can you replace "." with "_" for the purposes of redirection, and replace back in your action method? Otherwise, you have to look at ways you can get the routing not to interpret ".0" as a file extension. Not sure exactly how off of the top of my head...
MVC routes errors like this to special methods. One is in the controller: HandleUnknownAction, which is called when the action can't be matched. You can override it and handle the action (logging it, etc.) there.
Check this article, it has a solution for you:
From the link:
<configuration>
<system.web>
<httpRuntime relaxedUrlToFileSystemMapping="true"/>
<!-- ... your other settings ... -->
</system.web>
</configuration>
change the ROuteCOnfig to:
routes.MapRoute(
name: "Default2",
url: "{source}/{id}/",
defaults: new { controller = "Home", action = "Index" }
);
Should solve your issue.
You can also check this SO Thread
Related
I use VS2013 and created MVC application by wizard. I also deleted all extra files and have the following:
1) RouteConfig.cs
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
}
2) HomeController.cs
public class HomeController : Controller
{
[Route("Home/Index")]
public ActionResult Index()
{
return View();
}
}
3) Index.cshtml
#{
ViewBag.Title = "Home Page";
}
Home page
I've got the page with error:
HTTP 403.14 - Forbidden
But, if I add to URL in browser's address bar manually - Home/Index:
http://localhost:50600/Home/Index
The page appears.
What I'm doing wrong?
Remove the "Home" from the route as the controller name HomeController is already starting your route with "Home". If you want to change that "Home" prefix, you can add an attribute to the HomeController class to define that.
Also, the default route name for an action will match the action name, so in this case you could use [Route("")] and the url /Home/Index would work.
My guess is that when you try this url:
http://localhost:50600
It does not work because you have removed the default route from your routes config. I don't know if you removed it yourself, but RoutesConfig.cs file usually comes with the following default route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
This code ensures that if the user does not provide the controller or the action the site will default to index action of the home controller (you ca see that under the defaults parameter). This would also explain why it works when you try this route:
http://localhost:50600/Home/Index.
I think I know what's your problem now. You're expecting the default url to show up your Index View in HomeController but you've not setup the default route. You can set the default route by adding the following lines in your RouteConfig.cs
config.Routes.MapRoute(
name: "Default",
routeTemplate: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
Alternatively, if you wish to use attribute routing only without mixing with route template, you can just add the default route as following:-
config.Routes.MapRoute(
name: "Index",
url: "",
defaults : new { controller = "Home", action = "Index" }
);
I'm building an intranet where I have the following home controller:
[Route("{action=index}")]
public class HomeController : Controller
{
public ActionResult Index()
{
return View(HomeModelBuilder.BuildHomeModel());
}
public ActionResult FormsHome()
{
return View(HomeModelBuilder.BuildFormsHomeModel());
}
}
I'm trying to get my forms homepage to have a url of http://intranet/forms so I thought I could do this using the following routing attribute:
[Route("~/forms")] // have also tried 'forms' and '/forms'
public ActionResult FormsHome()
but when I go to the url, it complains that multiple controllers have that route:
The request has found the following matching controller types:
HRWebForms.Website.Controllers.ChangeDetailsController
HRWebForms.Website.Controllers.InternalTransferController
HRWebForms.Website.Controllers.LeaverController
...
I have also tried adding [RoutePrefix("")] to the controller but this didn't work either
Is there a way to give that action a url of "forms" (without any controller or without adding a separate forms controller with an index) by just using routing attributes?
You could try adding [RoutePrefix("forms")] to your controller, but this will result in all your actions expecting the same prefix.
There is a walkaround for this too (by using [Route("~/RouteParam/AnotherRouteParam")] to have Route "RouteParam/AnotherRouteParam") but it seems to me that FormsController would cost less work.
Ok so ranquild's comment pushed me in the right direction. In my route config, I had the default route of
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
So that my homepage would still work on the url with nothing in. If I changed this to
// Needed for homepage
routes.MapRoute(
name: "Home",
url: "",
defaults: new { controller = "Home", action = "Index" }
);
// Needed for Html.ActionLink to work
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = UrlParameter.Optional, action = UrlParameter.Optional }
);
It seemed to solve the problem
My end goal is to have a <Script> line in the _layout that will be generated from Database data. Step 1 for me is to simply display a comment line in the "head" portion of the page. I have a test program that does this just fine. When I copy the code over to my site I get "No route in the route table matches the supplied values." when I run the web. The error is pointing to the #Html.Action("OVars","MyO") statement in _layout.
I have tried to use Glimpse and RouteDebugger but I am not able to get any data on what this route actually is being generated as and then why it is failing. The output from RouteDebugger has a list of about 30 to 40 routes of which only the "Default" route is in Global.asax.cs. So I can only assume that these routes are being created elsewhere in the code.
#Html.Action("OVars","MyO")
The controller contains:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MySite.Controllers
{
public class MyOController : Controller
{
// ChildActionOnly will not allow direct displaying of this page
[ChildActionOnly]
public ActionResult OVars()
{
return PartialView("_OVars");
}
}
}
The _OVars partialview:
<!-- Test comment simply for displaying -->
Global.asax.cs
public static void RegisterRoutes(RouteCollection routes)
{
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new RazorViewEngine());
routes.IgnoreRoute("{resource}.ico");
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
Any suggestions on what to look at would be a help. For all I know there is a parameter set that I am not aware of that needs to be changed.
Thanks
Solved (but I do not understand "Areas, something more to learn").
I changed the line #Html.Action("OVars","MyO") to #Html.Action("OVars","MyO", new { area = string.Empty }).
I kept making code changes until I received an error message that when I looked it up found some text similar to "This error could also happen if inside a view in your area, you use the Html.Action helper. This helper will always use the area as a prepend, unless you specifically tell it not to.". The example presented was to add , new { area = string.Empty } to the #Html.Action statement.
Now the #Html.Action is working correctly and I can move forward with having the controller access the database for information.
Next up on the learning agenda is "Understanding Areas".
In case someone has the same struggle as me.
I had a custom route:
routes.MapRoute(
name: "MyPrefixRoute",
url: "myprefix/{code}/{name}",
defaults: new { controller = "Account", action = "MyPrefix", name = UrlParameter.Optional }
);
And then my default route (which is a slight variation of the MVC default route):
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}/{name}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional, name = UrlParameter.Optional }
);
The exception was only raised when browsing /myprefix/123/the-name and not /myprefix/123?name=the-name nor /myprefix/123.
The only thing that fixed it was to add a third custom route without UrlParameter.Optional:
routes.MapRoute(
name: "DefaultAction",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
Although it works now, I would be happy to get an explanation ;-)
I have an MVC application and am using the standard routeconfig that routes /Controller/Action/Id
I want it to additionally capture /Controller/Action.html as the url and as well and point to /controller/action also.
I am using a jquery library that I have no control over, and a function requires a url that points to a webpage or an image. However, it doesn't appear to understand that ends without an extension(.html, .php etc) is a link to html and throws an error.
Edit: I tried as the commenter below suggested, and still can't seem to get it to work. Here is my route config.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("routeWithHtmlExtension",
"{controller}/{action}.html",
new { controller = "Home", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
This Url works:
http://localhost:14418/Album/Test
This one does not:
http://localhost:14418/Album/Test.html
In web.config
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
...
</system.webServer>
If you set up the following route, it will work:
routes.MapRoute("routeWithHtmlExtension",
"{controller}/{action}.html",
new {controller = "Home", action = "Index" }
);
What my requirement is;
if I type www.mysite.com - it will load the front page.
But if I type www.mysite.com/john - it will return john's profile page.
John's profile is originally located in /Profile/John and this works fine. But the requirement is www.mysite.dom/John.
I am trying many ways with NO success. Would be nice if anyone can help me out.
cheers
Define two routes.
First to "/Profile/{name}", then to "/{name}", pointing to the same action.
If you want to use the same controller and have routes setup to respond to parameters, you can setup your routes like this too
routes.MapRoute(
name: "Meeting",
url: "{name}",
defaults: new
{
controller = "Home",
action = "Welcome"
}
);
routes.MapRoute(
name: "Default",
url:"",
defaults: new
{
controller = "Home",
action = "Index"
}
);
My HomeController looks like
public void Welcome(string name)
{
ViewBag.Title = "Home Page";
}
public ActionResult Index()
{
return View();
}