I have a controller named article and my articles in the url take the shape of {controller}/{action}/{id}/{title}/{mixed} how can i get that to {controller}/{id}/{title}/{mixed}
my route value is
routes.MapRoute(
"articles",
"{controller}/{action}/{id}/{stitle}/{mixed}",
new { controller = "article",action="detail",mixed= UrlParameter.Optional} // Parameter defaults
);
I have tried this
routes.MapRoute(
"articles", // Route name
"{controller}/{id}/{title}/{mixed}",
new { controller = "article",action="detail",mixed= UrlParameter.Optional}
);
but get a 404 error
as my links are in the form
#Html.ActionLink("My article", "detail", "article", new { id = item.ArticleID, title = item.title, mixed = item.mixed })
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"ArticleWithoutAction", // Article Without Action name
"{controller}/{id}/{name}",
new { controller = "Article",
action = "detail",
id = UrlParameter.Optional,
title = UrlParameter.Optional,
mixed = UrlParameter.Optional
} // Parameter defaults
);
routes.MapRoute(
"ArticleWithAction", // Article With Action name
"{controller}/{action}/{id}/{name}",
new { controller = "Article",
action = "detail",
id = UrlParameter.Optional,
title = UrlParameter.Optional,
mixed = UrlParameter.Optional
} // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}",
new { controller = "Article",
action = "detail"
} // Parameter defaults
);
}
I will bring code first.
Controller:
public ActionResult VideoList(int page)
{
}
[HttpPost]
public ActionResult SaveWindowWidth(string width)
{
return Json(new { success = true });
}
JS:
$(document).ready(function ()
{
var width = $("#Window").width();
$.ajax(
{
type: "POST",
url: '/Video/SaveWindowWidth',
async: "true",
data: { "width": width },
dataType: 'text json',
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
success: function (data, status)
{
if (data)
{
alert(data.status);
}
},
error: function (data, status)
{
if (data)
{
alert(data.status);
}
}
})
})
Routes:
routes.MapRoute(
"Home", // Route name
"Home", // URL with parameters
new { controller = "Home", action = "Index" }
);
routes.MapRoute(
"BookPage", // Route name
"BookPage/{page}", // URL with parameters
new { controller = "Book", action = "Page" }
);
routes.MapRoute(
"BlogMember", // Route name
"BlogMember/{id}/{page}", // URL with parameters
new { controller = "Blog", action = "Member" }
);
routes.MapRoute(
"BlogPost", // Route name
"BlogPost/{id}/{page}", // URL with parameters
new { controller = "Blog", action = "Post" }
);
routes.MapRoute(
"BlogPage", // Route name
"BlogPage/{page}", // URL with parameters
new { controller = "Blog", action = "Page" }
);
routes.MapRoute(
"BlogTag", // Route name
"BlogTag/{tag}/{page}", // URL with parameters
new { controller = "Blog", action = "Tag" }
);
routes.MapRoute(
"NewBlogPostComment", // Route name
"NewBlogPostComment", // URL with parameters
new { controller = "Blog", action = "NewBlogPostComment" }
);
routes.MapRoute(
"NewBlogPost", // Route name
"NewBlogPost", // URL with parameters
new { controller = "Blog", action = "NewBlogPost" }
);
routes.MapRoute(
"EditBlogPost", // Route name
"EditBlogPost/{id}", // URL with parameters
new { controller = "Blog", action = "EditBlogPost" }
);
routes.MapRoute(
"Account", // Route name
"Account", // URL with parameters
new { controller = "Account", action = "Update" }
);
routes.MapRoute(
"LogOff", // Route name
"LogOff", // URL with parameters
new { controller = "Account", action = "LogOff" }
);
routes.MapRoute(
"LogOn", // Route name
"LogOn", // URL with parameters
new { controller = "Account", action = "LogOn" }
);
routes.MapRoute(
"Register", // Route name
"Register", // URL with parameters
new { controller = "Account", action = "Register" }
);
//routes.MapRoute(
// "About", // Route name
// "About", // URL with parameters
// new { controller = "Home", action = "About" }
//);
routes.MapRoute(
"Contact", // Route name
"Contact", // URL with parameters
new { controller = "Home", action = "Contact" }
);
routes.MapRoute(
"UnderConstruction", // Route name
"UnderConstruction", // URL with parameters
new { controller = "Home", action = "UnderConstruction" }
);
routes.MapRoute(
"DisableBlogComment", // Route name
"DisableBlogComment/{id}", // URL with parameters
new { controller = "Blog", action = "DisableBlogComment" }
);
routes.MapRoute(
"DisableAllMemberBlogComments", // Route name
"DisableAllMemberBlogComments/{id}", // URL with parameters
new { controller = "Blog", action = "DisableAllMemberBlogComments" }
);
routes.MapRoute(
"DisableVideoComment", // Route name
"DisableVideoComment/{id}", // URL with parameters
new { controller = "Video", action = "DisableVideoComment" }
);
routes.MapRoute(
"DisableAllMemberVideoComments", // Route name
"DisableAllMemberVideoComments/{id}", // URL with parameters
new { controller = "Video", action = "DisableAllMemberVideoComments" }
);
routes.MapRoute(
"DisableMember", // Route name
"DisableMember/{id}", // URL with parameters
new { controller = "Member", action = "DisableMember" }
);
routes.MapRoute(
"NewPost", // Route name
"NewPost", // URL with parameters
new { controller = "Blog", action = "NewPost" }
);
routes.MapRoute(
"InactiveBlogPosts", // Route name
"InactiveBlogPosts/{page}", // URL with parameters
new { controller = "Blog", action = "InactiveBlogPosts" }
);
routes.MapRoute(
"InactiveBlogComments", // Route name
"InactiveBlogComments/{page}", // URL with parameters
new { controller = "Blog", action = "InactiveBlogComments" }
);
routes.MapRoute(
"InactiveVideoComments", // Route name
"InactiveVideoComments/{page}", // URL with parameters
new { controller = "Video", action = "InactiveVideoComments" }
);
routes.MapRoute(
"EditHomePage", // Route name
"EditHomePage", // URL with parameters
new { controller = "Home", action = "EditHomePage" }
);
routes.MapRoute(
"EditAboutPage", // Route name
"EditAboutPage", // URL with parameters
new { controller = "Home", action = "EditAboutPage" }
);
routes.MapRoute(
"Newsletter", // Route name
"Newsletter", // URL with parameters
new { controller = "Newsletter", action = "Newsletter" }
);
routes.MapRoute(
"RegisterNewVideo", // Route name
"RegisterNewVideo", // URL with parameters
new { controller = "Video", action = "RegisterNewVideo" }
);
routes.MapRoute(
"Members", // Route name
"Members/{page}", // URL with parameters
new { controller = "Member", action = "MemberList" }
);
routes.MapRoute(
"EditMember", // Route name
"EditMember/{id}", // URL with parameters
new { controller = "Member", action = "EditMember" }
);
routes.MapRoute(
"AppSettings", // Route name
"AppSettings", // URL with parameters
new { controller = "Utility", action = "AppSettings" }
);
routes.MapRoute(
"AudioBookPage", // Route name
"AudioBookPage/{page}", // URL with parameters
new { controller = "Book", action = "AudioBookPage" }
);
routes.MapRoute(
"IPBlocked", // Route name
"IPBlocked", // URL with parameters
new { controller = "Utility", action = "IPBlocked" }
);
routes.MapRoute(
"LiveTV", // Route name
"LiveTV", // URL with parameters
new { controller = "LiveTV", action = "LiveTV" }
);
routes.MapRoute(
"VideoPlayer", // Route name
"VideoPlayer/{id}/{page}", // URL with parameters
new { controller = "Video", action = "VideoPlayer" }
);
routes.MapRoute(
"Video", // Route name
"Video/{page}", // URL with parameters
new { controller = "Video", action = "VideoList" }
);
routes.MapRoute(
"NewVideoComment", // Route name
"NewVideoComment", // URL with parameters
new { controller = "Video", action = "NewVideoComment" }
);
routes.MapRoute(
"Music", // Route name
"Music", // URL with parameters
new { controller = "Music", action = "Index" }
);
routes.MapRoute(
"RootsCompilationOne", // Route name
"Music/RootsCompilationOne", // URL with parameters
new { controller = "Music", action = "RootsCompilationOne" }
);
routes.MapRoute(
"UnityIsStrength", // Route name
"Music/UnityIsStrength", // URL with parameters
new { controller = "Music", action = "UnityIsStrength" }
);
routes.MapRoute(
"FileUpload", // Route name
"FileUpload", // URL with parameters
new { controller = "Utility", action = "FileUpload" }
);
routes.MapRoute(
"PageUnavailable", // Route name
"PageUnavailable", // URL with parameters
new { controller = "Utility", action = "PageUnavailable" }
);
routes.MapRoute(
"VideoGrid", // Route name
"VideoGrid/{page}", // URL with parameters
new { controller = "Video", action = "VideoGrid" }
);
routes.MapRoute(
"EditVideo", // Route name
"EditVideo/{id}", // URL with parameters
new { controller = "Video", action = "EditVideo" }
);
routes.MapRoute(
"CopyVideo", // Route name
"CopyVideo/{id}/{page}", // URL with parameters
new { controller = "Video", action = "CopyVideo" }
);
routes.MapRoute(
"DeleteIPLogs", // Route name
"DeleteIPLogs/{ip}", // URL with parameters
new { controller = "Utility", action = "DeleteIPLogs" }
);
routes.MapRoute(
"SaveWindowWidth", // Route name
"SaveWindowWidth/{width}", // URL with parameters
new { controller = "Video", action = "SaveWindowWidth" }
);
routes.MapRoute(
"FacebookLikes", // Route name
"FacebookLikes", // URL with parameters
new { controller = "Utility", action = "FacebookLikes" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
Problem that ajax tries to call VideoList method. I see it when read response:
The parameters dictionary contains a null entry for parameter 'page' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult VideoList(Int32)'
I have heard somewhere that it may be something wrong with routes, so I posted them here as well.
I would appreciate your help
Regards
Mariusz
Your video route is not well configured. MVC tries to get the controller and action from each url to figure out required method from appropriate controller. And in your case, it always gets same values VideoController.VideoList():
routes.MapRoute(
"Video", // Route name
"Video/{page}", // URL with parameters
new { controller = "Video", action = "VideoList" }
);
If you change your route to this, everything will be ok:
routes.MapRoute(
"Video", // Route name
"Video/{action}", // URL with parameters
new { controller = "Video", action = "VideoList" }
);
Dima has identified the issue, though his solution wouldn't quite work for you. Your routes are configured such that when requesting a url Video/SaveWindowWidth, call the action VideoList on the controller Video with the parameter page set to SaveWindowWidth. Clearly that is not what you wanted.
ASP.Net MVC will execute the first route that matches. Which is why it's important to include all specific routes first.
One of the ways to fix this is to re-write your routes such that certain API routes are configured above your generic pretty routes. To do so, you would need to mention every single combination before any pretty url.
For example,
routes.MapRoute(
"SaveWindowWidthForVideo", // Route name
"Video/SaveWindowWidth",
new { controller = "Video", action = "SaveWindowWidth" }
);
routes.MapRoute(
"SaveWindowHeightForVideo", // Route name
"Video/SaveWindowHeight",
new { controller = "Video", action = "SaveWindowHeight" }
);
routes.MapRoute(
"SaveWindowSomethingElseForVideo", // Route name
"Video/SaveWindowHeight",
new { controller = "Video", action = "SaveWindowSomethingElseForVideo" }
);
// etc etc
// your remaining pretty urls
routes.MapRoute(
"Video", // Route name
"Video/{page}", // URL with parameters
new { controller = "Video", action = "VideoList" }
);
I don't prefer to do that, as it can get rather cumbersome very easily.
The solution I prefer is to distinguish between my pretty url routes and my ajax API routes by adding the word api in the url.
routes.MapRoute(
"ApiCallsForVideo", // Route name
"api/video/{action}",
new { controller = "Video" }
);
// or
routes.MapRoute(
"ApiCalls", // Route name
"api/{controller}/{action}"
);
// etc etc
routes.MapRoute(
"Video", // Route name
"Video/{page}", // URL with parameters
new { controller = "Video", action = "VideoList" }
);
This obviously involves modifying your ajax calls to include the word api.
Use string to store value as URL is not a best practice.
I do something like this.
View
#Html.Hidden("getVideoUrl", Url.Action("SaveWindowWidth", "Video"))
JS
var url = $("#getVideoUrl").val();
$.post(url, data: { "width": width },
success: function (data, status)
{
if (data)
{
alert(data.status);
}
},
error: function (data, status)
{
if (data)
{
alert(data.status);
}
});
Hi i think you need to add parameter in route then only your ajax will call that method with parameter. Now whats happening is ur ajax is calling that particular methot but you 've not mentioned in route that to allow parameter
routes.MapRoute(
"Video", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Video", action = "VideoList", width= UrlParameter.Optional } // Parameter defaults
);
then only ur parameter can be passed to ur controller.
and calling url will look like this
url: '/Video/SaveWindowWidth'+width,
or
url: '/Video/SaveWindowWidth?width=' + width,
its working fine for me!
Hope it helps
I am looking to create a MVC3 website. We need at least two areas but we need different url's for each of the areas. Like this:
domain.com/ goes to /
admin.domain.com/ goes to /areas/admin
anotherSite.com/ goes to /areas/portal
After doing some research I have found Lucero's link that you can use HostNameContraint as follows:
public class HostNameContraint : IRouteConstraint
{
protected string _hostname;
public HostNameContraint(string hostname)
{
_hostname = hostname;
}
bool IRouteConstraint.Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if (httpContext.Request.Url.Host == _hostname)
return true;
return false;
}
}
and then register the constraints like this:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { area = "", controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { hostname = new HostNameContraint("domain.com") },
new[] { "MVCProject.Controllers" }
);
routes.MapRoute(
"Admin_Default2", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { area = "Admin", controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { hostname = new HostNameContraint("admin.domain.com") },
new[] { "MVCProject.Controllers.Areas.Admin.Controllers" }
);
routes.MapRoute(
"Portal_Default2", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { area = "Portal", controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { hostname = new HostNameContraint("anotherSite.com") },
new[] { "MVCProject.Controllers.Areas.Portal.Controllers" }
);
I have IIS setup so that they point to the root folder of the application for each of the sites. Pointing to the root "Domain.com" works fine but going to either "Admin.domain.com" or "Domain.com/admin/" comes up with a 404 "Resource cannot be found."
Update
I have tried it both with the Area name at the beginning of the url and without.
"Portal/{controller}/{action}/{id}"
The issue is that when the "Portal" area is in the route, the signature does not match the name as "anotherSite.com" and therefore it comes back and says 403.14 - Forbidden. Cannot list contents of this directory. It is also important to note that the constructor for HostNameConstraint is never called when the "Portal" area is url parameter.
In order to indicate distinguish the URL as going to an area, the area name needs to be part of the URL. Otherwise, the area will not be parseable from the URL and you will fall back to the default routing. Also, it is a good idea to put your default route last - to ensure all other route mappings are tested
Note the addition of "Admin/" and "Portal/" in the corresponding MapRoute call:
routes.MapRoute(
"Admin_Default2", // Route name
"Admin/{controller}/{action}/{id}", // URL with parameters
new { area = "Admin", controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { hostname = new HostNameContraint("admin.domain.com") },
new[] { "MVCProject.Controllers.Areas.Admin.Controllers" }
);
routes.MapRoute(
"Portal_Default2", // Route name
"Portal/{controller}/{action}/{id}", // URL with parameters
new { area = "Portal", controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { hostname = new HostNameContraint("anotherSite.com") },
new[] { "MVCProject.Controllers.Areas.Portal.Controllers" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { area = "", controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { hostname = new HostNameContraint("domain.com") },
new[] { "MVCProject.Controllers" }
);
Using the following code:
#Html.ActionLink("News", "Index", new { controller = "News", area = "" }, new { #class = "News" })
I'm getting an error so that when I'm on a particular news article, the link is generating as:
http://mywebsite/News/2011/12/2/my_slug
where the parameters match the page that I'm currently on. The also happens on other controllers matching the same url schema (imagine I have another controller called Presentations that matches the url scheme of News entirely). From the presentations pages, a link to news would include the presentations parameters which aren't valid input for the news controller. Make sense?
I have my routes defined as:
routes.MapRoute(
"News-Archive", // Route name
"News/Archive", // URL with parameters
new { controller = "News", action = "Archive" }, // Parameter defaults
new[] { "mywebsite.Controllers" }
);
routes.MapRoute(
"News-Stub", // Route name
"News/{year}/{month}/{date}/{slug}", // URL with parameters
new { controller = "News", action = "Index" }, // Parameter defaults
new[] { "mywebsite.Controllers" }
);
routes.MapRoute(
"News-ByDay", // Route name
"News/{year}/{month}/{day}", // URL with parameters
new { controller = "News", action = "Archive" }, // Parameter defaults
new[] { "mywebsite.Controllers" }
);
routes.MapRoute(
"News-ByMonth", // Route name
"News/{year}/{month}", // URL with parameters
new { controller = "News", action = "Archive" }, // Parameter defaults
new[] { "mywebsite.Controllers" }
);
routes.MapRoute(
"News-ByYear", // Route name
"News/{year}", // URL with parameters
new { controller = "News", action = "Archive" }, // Parameter defaults
new[] { "mywebsite.Controllers" }
);
routes.MapRoute(
"News-Default", // Route name
"News", // URL with parameters
new { controller = "News", action = "Index" }, // Parameter defaults
new[] { "mywebsite.Controllers" }
);
Can someone please explain if the problem lies in my use of Html.ActionLink or my route definitions?
EDIT:
Changing the Actionlink to:
#Html.ActionLink("News", "Index", new { controller = "News", area = "", year = string.Empty, month = string.Empty, day = string.Empty, slug = string.Empty}, null)
results in this when called from a presentation page (those values are for the presentation, not a valid news item):
http://mywebsite/News?year=2011&month=12&slug=seo_overview
Not sure why that's causing the rewriting to change.
The action link assumes the current slug since no slug was provided:
Use
ActionLink("News", "Index", new { controller = "News", area = "", slug="newslug"}, new { #class = "News" })
or
ActionLink("News", "Index", new { controller = "News", area = "", slug = null}, new { #class = "News" })
There is a chance that setting the slug = null would also re-use the current slug, in that case set the slug = Empty String.
If i go to mysite/Catalog it breaks. How can solve it?
routes.MapRoute(
"Localization", // Route name
"{lang}/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", 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
);
routes.MapRoute(
"Root",
"",
new { controller = "Home", action = "Index", id = "" }
);
It will match your first route thinking "Catalog" is "lang". You need to create constraint for your localizations.
Following route should match requests prefixed with any language code (like en, cs, de or en-US, en-GB...) correctly
routes.MapRoute("Localization", "{lang}/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new { lang = "[a-z]{2}(-[a-z]{2})" }
);