I have the following controller within my MVC project:
public class PressController : Controller
{
// GET: Press
public ActionResult Index()
{
return File("../press/FFF_PRESS.zip", ".zip");
}
}
My routes
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
When I load the site my URL is as follows:
www.example.com
Which displays the home page correctly, when I click on the following Action <li class="footer__navEl"><a href='#Url.Action("Index", "Press")'>PRESS</a></li>
I would like the URL to be
www.example.com/press
and return the zip file.
However when I click this Action I get the following:
HTTP Error 403.14 - Forbidden
The Web server is configured to not list the contents of this directory.
Yet when I specify
www.example.com/press/index
The .zip file is returned correctly.
Now I added the following to my routes.config:
routes.MapRoute("Press", "Press", new { controller = "Press", action = "Index" });
I still get the same error mentioned above, can someone shed some light into what I might be missing to get this to perform correctly?
HTTP Error 403.14 - Forbidden The Web server is configured to not list the contents of this directory.
The error indicates you have a physical directory on your web server named press. What is happening is that the web server is returning the directory instead of passing the request on to MVC. The default setting in IIS is not to list the directory's contents, hence the error.
You need to either delete the press directory (recommended), or reconfigure IIS to run the MVC module instead of the directory by using the runAllManagedModulesForAllRequests, which has some caveats.
This isn't a routing problem at all - it is a webserver configuration problem.
NOTE: This is not a duplicate of another question as my first page works fine, it is other pages/actions that are not working.
I've ready many posts so far and nothing comes close. This works just fine when run locally on my development box. After I copy to the server, I see the problem. My default route works fine, I get the expected index page.
public ActionResult Index()
{
return View();
}
My RouteConfig contains:
routes.MapRoute(
name: "AnnualFees",
url: "{controller}/{action}/{id}",
defaults: new { controller = "AnnualFees", action = "Index", id = UrlParameter.Optional }
);
Problems arise when I want to reach anything other than Index. For example, this action causes a 404 not found error:
public ActionResult renderForm()
{
return PartialView("_formPanel");
}
Again, works as it should on my local dev box. But on the server I get Requested URL: /AnnualFees/renderForm 404 error The resource cannot be found.
UPDATE
Ok, doing some more research and trial and error, I discovered something and have a bit more to add.
This app is running under a current website in IIS, where I created a Virtual Folder/application under the website root. If I navigate to www.mysite.com/AnnualFees I get the first page of my MVC app as expected. However, the only way I can get to any other action in my AnnualFeesController, I have to double up the controller name like www.mysite.com/AnnualFees/AnnualFees/renderForm which works but is ugly and not quite right. How can I get rid of the redundancy?
So the problem, as I noted in the comment, is that you have a folder, and under it goes the route. If you do not provide any parts of the route, just calling
www.mysite.com/AnnualFees
this uses all defaults as specified in your route config, and you get the default page. However if you type
www.mysite.com/AnnualFees/ActionName
MVC sees that as controller ActionName and no action no id provided. This does not exist in your app, thus the error.
The root problem here is that websites are not supposed to live under folders, they are supposed to live under top domains. That is, it is not expected that site root URL is www.mysite.com/AnnualFees, it is supposed to be just www.mysite.com. But even that would be fine if you did not have your main controller and IIS folder with the same names, producing unwanted duplication.
You can however change you route to make AnnualFees a default controller. Simply remove the controller part like so:
routes.MapRoute(
name: "AnnualFees",
url: "{action}/{id}",
defaults: new { controller = "AnnualFees", action = "Index", id = UrlParameter.Optional }
);
Now you should be able to use
www.mysite.com/AnnualFees/ActionName
Again, note that in the above URL "AnnualFees" is not a controller name, it is in fact no visible to MVC app at all.
There is however a caveat. Imagine you need to add another controller. Now the default and only route would not work with it. The key is to provide a separate route for this controller, with hardcoded first part
routes.MapRoute(
name: "NewControllerRoute",
url: "NewControllerName/{action}/{id}",
defaults: new { controller = "NewController", action = "Index", id = UrlParameter.Optional }
);
Make sure to put this route before the default one, so that all requests to this controller are routed correctly, and all other requests go to "AnnualFees".
My scenario is as follows: a venue can be part of multiple categories and users can also add filters on multiple category types, so my URLs now are like:
/venues/beaches/boats/themeparks
(this will display all venues that are beaches AND boats AND themeparks)
/venues/beaches/boats
/venues etc.
So the number of different venue types (beaches, boats, themeparks etc) is both dynamic AND optional. How can I setup my rewrite rules that the category querystring parameter holds all the different venue types or preferably the category parameter is added multipe times and if no venuetype is provided category will just be empty/null?
So for URL: /venues/beaches/boats/themeparks
I'd get this rewritten URL: search.aspx?category=beaches&category=boats&category=themeparks
And for URL: /venues
I'd get this rewritten URL: search.aspx?category= (or fine too would be: search.aspx)
I now just have this:
<rule name="venue types">
<match url="^venues/([a-zA-Z0-9-+']+)$"/>
<action type="Rewrite" url="search.aspx?category={R:1}"/>
</rule>
update
I went with the below suggestion of #Arindam Nayak.
I installed https://www.nuget.org/packages/Microsoft.AspNet.FriendlyUrls.Core/ and manually created a RouteConfig.vb file in App_Start folder. I added (as a test):
Public NotInheritable Class RouteConfig
Private Sub New()
End Sub
Public Shared Sub RegisterRoutes(routes As RouteCollection)
Dim settings = New FriendlyUrlSettings()
settings.AutoRedirectMode = RedirectMode.Permanent
routes.EnableFriendlyUrls(settings)
routes.MapPageRoute("", "test", "~/contact.aspx")
End Sub
End Class
And in global.aspx.vb I added:
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
RouteConfig.RegisterRoutes(RouteTable.Routes)
End Sub
When I go to www.example.com/test, it does now correctly redirect me to contact.aspx. (Be aware: URL Rewriting - so rules in web.config or rewriteRules.config file - take precedence over RouteConfig.vb!)
I'm almost there, so this www.example.com/test redirects correctly to file contact.aspx
But this www.example.com/test/boats/outside/more/fields/are/here, throws a 404 error:
update 2
I added logging to routeConfig.vb:
GlobalFunctions.Log("1")
Dim settings = New FriendlyUrlSettings()
GlobalFunctions.Log("2")
settings.AutoRedirectMode = RedirectMode.Permanent
GlobalFunctions.Log("3")
routes.EnableFriendlyUrls(settings)
GlobalFunctions.Log("4")
routes.MapPageRoute("", "test", "~/contact.aspx")
GlobalFunctions.Log("5")
And these lines are all executed. Now something strange is happening:
routeConfig.vb seems to only be executed once. So:
I build my app.
I goto /test URL
the lines are logged and I arrive on the contact.aspx page
I refresh the /test page, NO lines are logged
And I also tried:
I build my app.
I goto /test/boats/outside/more/fields/are/here URL
the lines are logged
I get the aforementioned 404 error
I refresh the page, nothing is logged anymore
So it seems routeConfig is only ever hit once (at applicationstart?) and then never hit again. And for request /test/boats/outside/more/fields/are/here it arrives at routeConfig.vb file, but does not show contact.aspx for some reason...
update 3
I found that when I explicitly define the routes, it does work, like so:
routes.MapPageRoute("", "test", "~/contact.aspx")
routes.MapPageRoute("", "test/123", "~/contact.aspx")
So now URL /test and /test/123 work, but that is not dynamic at all as I just want to match on /test and then get the FriendlyUrlSegments.
I can't post the code online, so if it helps, here's my solution explorer:
What can I do?
To have such kind of SEO friendly URL you need to install “Microsoft.AspNet.FriendlyUrls” nuget package.
Open package manager console – Help. Then type following –
Install-Package Microsoft.AspNet.FriendlyUrls
Then it will automatically add following in RouteConfig.cs.
public static class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
var settings = new FriendlyUrlSettings();
settings.AutoRedirectMode = RedirectMode.Permanent;
routes.EnableFriendlyUrls(settings);
}
}
For you case, you need to add following to RouteConfig.cs.
routes.MapPageRoute("", "venues", "~/venues.aspx");
So when you hit url http://www.example.com/venues/beaches/boats/themeparks or http://www.example.com/venues/beaches, it will hit venues.aspx. In venues.aspx.cs, page_load event you need to have following code.
IList<String> str = Request.GetFriendlyUrlSegments();
For case-1, str will be ['beaches','boats','themeparks'] and for case-2 it will be ['beaches'].
For more info you can refer to my blog or similar SO answer here - Reroute query string using friendlyUrl
Let me know,if you face any issue or still your issue is unresolved.
I want create web application with 2 parameter. Add this Code to RegisterRoutes function:
routes.MapRoute(
"pageroute",
"page/{pageid}/{pagename}",
new { controller = "page", action = "Index", pageid = "", pagename = "" }
);
and add this method in pageController:
public ActionResult Index(int pageid,string pagename)
{
return View();
}
Now when i running application with this parameter
http://localhost:1196/page/4/Pagename
Application run successfully but when running with this parameter
http://localhost:1196/page/4/Pagename.html
Application return 404 error
HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
while add .html in parameter return 404 error. why?
Because by default HTML files are not being served through MVC/IIS.
Your application looks for a physical file named Pagename.html and cannot find it there. Hence - 404.
To make it work, you need to setup your IIS to catch requests for files with HTML extension and pass this request to MVC.
EDIT: Here is a similar question where OP found a solution by switching "Managed Pipeline Mode" to "Classic".
Try changing the Route to:
routes.MapRoute(
"pageroute",
"page/{pageid}/{*pagename}",
new { controller = "page", action = "Index", pageid = "", pagename = "" }
);
This will then match everything as in page/1/* so the .html should go via this route.
I was unable to reproduce an issue where a .html file gave a 404 using a scenario similar to the question, so there may be some other routing issue or IIS configuration causing this.
I'm doing an ASP.NET MVC 3 web service and I keep getting this exception intermittently.
Stack trace:
Server Error in '/' Application.
A route named 'ListTables' is already in the route collection. Route names must be unique.
Parameter name: name
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentException: A route named 'ListTables' is already in the route collection. Route names must be unique.
Parameter name: name
Source Error:
Line 24: // }
Line 25: // );
Line 26: context.MapRoute(
Line 27: "ListTables",
Line 28: // example:
Source File: C:\inetpub\wwwroot\SchemaBrowserService\Website\Areas\Api\ApiAreaRegistration.cs Line: 26
Stack Trace:
[ArgumentException: A route named 'ListTables' is already in the route collection. Route names must be unique.
Parameter name: name]
System.Web.Routing.RouteCollection.Add(String name, RouteBase item) +2329682
System.Web.Mvc.RouteCollectionExtensions.MapRoute(RouteCollection routes, String name, String url, Object defaults, Object constraints, String[] namespaces) +236
System.Web.Mvc.AreaRegistrationContext.MapRoute(String name, String url, Object defaults, Object constraints, String[] namespaces) +59
System.Web.Mvc.AreaRegistrationContext.MapRoute(String name, String url, Object defaults) +17
SchemaBrowserService.Areas.Api.ApiAreaRegistration.RegisterArea(AreaRegistrationContext context) in C:\inetpub\wwwroot\SchemaBrowserService\Website\Areas\Api\ApiAreaRegistration.cs:26
System.Web.Mvc.AreaRegistration.CreateContextAndRegister(RouteCollection routes, Object state) +105
System.Web.Mvc.AreaRegistration.RegisterAllAreas(RouteCollection routes, IBuildManager buildManager, Object state) +199
System.Web.Mvc.AreaRegistration.RegisterAllAreas(Object state) +45
System.Web.Mvc.AreaRegistration.RegisterAllAreas() +6
Website.MvcApplication.Application_Start() in C:\Users\djackson\Downloads\RestApiMvc3\Website\Website\Global.asax.cs:35
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.272
It's probably related to the fact that Route Debugger shows that I have some old routes that I've modified or deleted and won't go away (even after rebooting my machine). The stack trace also refers to a source file that has long since been deleted and my app has been moved to a new location, cleaned and rebuilt since then. What am I missing?
Here is all of my route registration code:
// in Global.asax.cs:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default2", // Route name
"Api/{controller}/{action}/{id}", // URL with parameters
new { controller = "DataSource", action = "Index", area = "Api", 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
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
// in ApiAreaRegistration.cs:
public class ApiAreaRegistration : AreaRegistration
{
public override string AreaName { get { return "Api"; } }
public override void RegisterArea(AreaRegistrationContext context)
{
// DataSources
// Tables
context.MapRoute(
"ListTables",
// example:
// /api/DataSources/DataSource/1/schemata/schema/dbo/tables
"Api/DataSources/DataSource/{dataSourceId}/schemata/{schemaName}/tables",
new
{
controller = "Tables",
action = "TableList",
schemaName = "dbo",
dataSourceId = "DefaultId"
}
);
// Schemata
context.MapRoute(
"Schema",
// example:
// /api/DataSources/DataSource/1/schemata/schema/dbo
"Api/DataSources/DataSource/{dataSourceId}/schemata/{schemaName}",
new
{
controller = "Schema",
action = "Schema",
dataSourceId = "DefaultId",
schemaName = UrlParameter.Optional
}
);
// // DataSources
context.MapRoute(
"SingleDataSource",
"Api/DataSources/DataSource/{dataSourceId}",
new
{
controller = "DataSource",
action = "DataSource",
dataSourceId = UrlParameter.Optional
}
);
context.MapRoute(
"ListDataSources",
"Api/DataSources",
new
{
controller = "DataSource",
action = "DataSourceList",
dataSourceId = "DefaultId"
}
);
context.MapRoute(
"Api_default",
"Api/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
To fix this problem I had to go into the bin folder on my project, delete all DLL files and then rebuild and this fixed the problem.
This error can occur due to multiple causes, I had the same error and solved it by modifying the Global.asax class.
The Application_Start method at Global.asax.cs was like:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
RouteConfig.RegisterRoutes(RouteTable.Routes);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
The following line occurs twice in this method:
RouteConfig.RegisterRoutes(RouteTable.Routes);
This ensured that the route was twice added to the route list and at the same time causing the error.
I changed the Application_Start method as follows and the error disappeared:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
This may not be the answer for your problem, but can perhaps help others in the future. I didn't see this answer between the others, so I decided to add this.
I found out that Global.asax was referring to an old version of the site's DLL file before I renamed it. The DLL was not being cleaned up when I did Build > Clean up because the VS project/solution didn't refer to it any more. It seems that sometimes only the newer version of the DLL was being used, allowing the site to work correctly, but eventually both of them would be loaded causing the route conflicts.
The routes get loaded from all assemblies within AppDomain.CurrentDomain, so if your old assemblies are still part of that, you might be still getting old/duplicate routes.
In my case, I faced with this issue, when I added reference to another project from solution, which also was MVC and use the same names in area (I didn't want to added this project, I don't know how it happened). When I removed this DLL, project started to work.
Deleting the DLLs alone didn't work for me (in VS2013), but deleting the entire 'bin' and 'obj' folders and then building the solution worked perfectly! Makes me wish I hadn't spent so long trying to fix it...
None of the suggestions worked for me. Went ahead and restarted the web server (IIS in this case) and that cleared the error after I had fixed the code. DLL must have been cached in IIS.
try this code, only change name
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapHttpRoute(
name: "API",
routeTemplate: "api/{controller}/{action}",
defaults: new { action = "GetAgentId" }
);
I am getting same error. But finally I have got solution.
Scenario: I am adding different(mvc4 application) dll in my web api mvc4 application.
When try to run. I am getting same error.
Root Cause- When my web api application run .Application register all area from self and start loading to current application domain dll references. When application load dll(MVC4 application) that time getting error because current maproute already add key for "HelpPage_Default".
Solution.
1.Change key for RegisterArea in maproute either current application or existing application(Refer dll).
2.Move code dll(mvc4 application) code to different liberary and refer to new dll.
I was manually calling AttributeRoutingHttpConfig.Start() in my Global.asax. Did not notice this auto-generated line at the top of the file which automatically calls it.
[assembly: WebActivator.PreApplicationStartMethod(typeof(Mev.Events.Web.AttributeRoutingHttpConfig), "Start")]
I had an application that was a Forms app migrated to MVC with a third party component used for authentication which redirected to another site.
The component would start a session twice if the user wasn't already logged in (once for initial connection to site and once for return).
So I solved this with the following code:
if (routes.Count < 3)
{
routes.IgnoreRoute("login.aspx");
routes.IgnoreRoute("default.aspx");
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new {action = "Index", id = UrlParameter.Optional}
);
}
Deleting the dlls in the bin folder did work 100%, I still had dlls my project needed to rebuild.
Rather make a copy of the bin folder. then delete the original.rebuild the project. if it fails, place the missing dlls into the bin folder.
I was running an old MVC2 website and I got this issue because the IIS 'Managed Pipeline Mode' was set on 'Integrated' by default (press F4 on the project). Changing it to 'Classic' fixed the issue
When publishing to an Azure App Service I had to check the Publish Dialog's "Settings"->"File Publish Options"->"Remove additional files at destination" to get the old project DLL and symbol files removed. Then the site would load.
This is essentially the current answers (Fleas's) solution at the core. Delete the offending DLL.
What caused this old DLL to be retained was I was loading an older version of the website (MVC 3~5 templates but different web project with colliding namespaces, since the newer version was a copy of this project made some point in the recent past.) The newer project's DLLs just needed to be deleted. There are various ways to achieve this. I found using a dialog to be the easiest atm. Logging into the file system and axing the files by hand certainly works too.
If you are versioning, and you use two APIs with the same name, you will get this error. If you need the same Get, try changing the Name attribute of the route:
TestsController.cs:
[MapToApiVersion("1.0")]
[Route("{moniker}", Name = "GetTest")]
public async Task<IHttpActionResult> Get(string moniker, bool param1 = false)
[MapToApiVersion("1.1")]
[Route("{moniker}", Name = "GetTest11")] // Change name here for a different version
public async Task<IHttpActionResult> Get(string moniker)
And pass in the version in the URL:
http://localhost:6600/api/tests/2020?api-version=1.1
faced this issue. the problem was occurred after adding an area to my project. there was a call for MapMvcAttributeRoutes() in RegisterArea() method. therefore, you should not look for a duplicate route names, just look for duplicate MapMvcAttributeRoutes() calls.