I haved added this routing to my global asax.
routes.MapRoute(
"News", // Route name
"News/{timePeriod}/{categoryName}/{page}", // URL with parameters
new { controller = "News", action = "Index",
timePeriod = TimePeriod.AllTime, categoryName = "All", page = 1 },
new { page = #"^\d{1,3}$" }// Parameter defaults
);
routes.MapRoute(
"News2", // Route name
"News/{categoryName}/{page}", // URL with parameters
new { controller = "News", action = "Index",
timePeriod = TimePeriod.AllTime, categoryName = "All", page = 1 },
new { page = #"^\d{1,3}$" }// Parameter defaults
);
The problem is urls like /News/add wont work (unless i add the specific route)
is there a better way without having to specify url action in global asax?
I think, that would catch it. But only, if you won't pass any extra arguments like id (because, then it's very similar to News2 route).
routes.MapRoute(
"News0",
"News/{action}",
new { controller = "News", action = "Index" }
);
Also, try Routing Debugger to test for effect you want:
link
Your two routes above will each route to the News controller and hit the "Index" action. If you don't have overloads for the Index action that will take the parameters you are specifying then the route won't work properly. For instance, you should have these two actions:
public ActionResult Index(TimePeriod timePeriod, string categoryName, int page) {..}
public ActionResult Index(string categoryName, int page) {..}
Also, you should remove the default parameter of TimePeriod from your second route since you aren't using it in the route itself:
routes.MapRoute(
"News2", // Route name
"News/{categoryName}/{page}", // URL with parameters
new { controller = "News", action = "Index", categoryName = "All", page = 1 },
new { page = #"^\d{1,3}$" }// Parameter defaults
);
I would recommend having an action for every category instead of creating a route for each category. You could simplify your routes to this:
routes.MapRoute(
"News", // Route name
"News/{action}/{timePeriod}/{page}", // URL with parameters
new { controller = "News", action = "Index", timePeriod = TimePeriod.AllTime, categoryName = "All", page = 1 },
new { page = #"^\d{1,3}$" }// Parameter defaults
);
Then having an action for each category:
public ActionResult All(TimePeriod timePeriod, string categoryName, int page) {..}
public ActionResult Sports(TimePeriod timePeriod, string categoryName, int page) {..}
public ActionResult Weather(TimePeriod timePeriod, string categoryName, int page) {..}
This way all you will need is the one route.
Related
It's late, I've had a lot happen today and I must be missing something very simple.
I have a route such as this:
routes.MapRoute("RequestKey", "License/RequestKey/{apello}/{requestcipher}",
new { controller = "ProductKey", action = "RequestKey" },
new { apello = "", requestcipher = "" },
new[] { "....Controllers" }
My controller action:
[ChildActionOnly]
public string RequestKey(string apello, string requestcipher)
{
return "Yeah";
}
And the url doesn't hit the controller action....time for bed?
http://localhost:53764/License/RequestKey/qwerqewrqwr/zxcvzcvzcx
Your tags indicate that you are using ASP.NET MVC 4, then try this route mapping:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{param1}/{param2}",
defaults: new { controller = "Home", action = "Index", param1 = UrlParameter.Optional, param2 = UrlParameter.Optional }
);
If you have the possibility to upgrade to ASP.NET MVC 5 then you can use Attribute routing and you should then have the possibility to write custom routes next to your Controller Action methods like this..
[Route("License/RequestKey/{apello}/{requestcipher}")]
public string RequestKey(string apello, string requestcipher)
{
return "Yeah";
}
I am working on a social networking site where we are implementing profiles, pages, groups etc. At this stage, we are working with profiles and pages. They both have wall where user can put some status, pics etc, more like facebook wall.
Now a controller WallController can be accessed by two different urls.
www.mysite.com/profile/121/some-user/wall
and
www.mysite.com/page/222/some-page/wall
On the left hand side of the page, I load some basic information (name etc) and a menu.
saying
www.mysite.com/profile/121/some-user/photos
www.mysite.com/profile/121/some-user/videos
www.mysite.com/profile/121/some-user/songs
This applies to both (page and profile).
here is my route for page
routes.MapRoute(
"Page-wall", // Route name
"page/{id}/{name}/wall", // URL with parameters
new { controller = "wall", action = "details", id = "", name = "" },
new { id = #"\d+" },
new string[] { "PagesNameSpace.Controllers" } // Parameter defaults
);
and for profile
routes.MapRoute(
"profile-wall", // Route name
"profile/{id}/{name}/wall", // URL with parameters
new { controller = "wall", action = "details", id = "", name = "" },
new { id = #"\d+" },
new string[] { "ProfileNameSpace.Controllers" } // Parameter defaults
);
Now, the problem is, I have to identify what object is accessing the url. here is my WallController
public class WallController : Controller
{
public ActionResult Details(long id, string name)
{
return View(LoadWallData(id));
}
}
I see a route value dictionary as a solution, but would like to see, what is the best solution for this kind for situations.
help will be appreciated.
Regards
Parminder
I would probably do the following, you just add the values into your routes:
Change your controller:
public class WallController : Controller
{
public ActionResult Details(long id, string name, string obj)//added param
{
return View(LoadWallData(id));
}
}
And then your routes:
routes.MapRoute(
"Page-wall", // Route name
"page/{id}/{name}/wall", // URL with parameters
new { controller = "wall", action = "details", id = "", name = "",
/*See this>>>> */ obj="page"},
new { id = #"\d+" },
new string[] { "PagesNameSpace.Controllers" } // Parameter defaults
);
routes.MapRoute(
"profile-wall", // Route name
"profile/{id}/{name}/wall", // URL with parameters
new { controller = "wall", action = "details", id = "", name = "",
/*See this>>>> */ obj="profile" },
new { id = #"\d+" },
new string[] { "ProfileNameSpace.Controllers" }
);
using ((System.Web.Routing.Route)(Url.RequestContext.RouteData.Route)).Url you can get the URL with parameter values from MapRoute.
I feel, I would go with this approach.
public class WallController : Controller
{
public ActionResult Details(string type ,long id, string name)//added param
{
return View(LoadWallData(id));
}
}
and my routes
routes.MapRoute(
"wall-default", // Route name
"{type}/{id}/{name}/wall", // URL with parameters
new { controller = "wall", action = "details", id = "", name = "",
type="profile"},
new { id = #"\d+" },
new string[] { "PagesNameSpace.Controllers" } // Parameter defaults
);
Now just by passing the type parameter, I can get action link for page and profile.
thanks a lot to everyone.
Regards
I'd like to map a new route after I commit a new object to db. So for example if i enter object with name "Test" I would like to have a new route immediately, to resolve "Test.aspx".
I tried
System.Web.Routing.RouteTable.Routes.MapRoute(obj.NameUrl, obj.NameUrl + extension, new { controller = "per", action = "Index", name = obj.NameUrl });
in controller but it does not work (no error, just probably not right time in life cycle?). Same code works in Application_Start()
You should avoid registering routes dynamically. The following static route in your Application_Start should be able to handle your scenario of having dynamic route parameters:
routes.MapRoute(
"page",
"{name}.aspx",
new { controller = "per", action = "index" },
new { name = #"[a-z0-9]+" }
);
and if the extension has to be dynamic as well:
routes.MapRoute(
"page",
"{name}.{extension}",
new { controller = "per", action = "index" },
new { name = #"[a-z0-9]+", extension = #"[a-z]{3,4}" }
);
and then you could have the Index action to handle requests to this route:
public class PerController: Controller
{
public ActionResult Index(string name, string extension)
{
...
}
}
and if you want to generate a link to this action:
#Html.RouteLink("go to foo", "page", new { name = "foo", extension = "aspx" })
I have functionality on my site to create/edit/delete pages for the front end. Here's my controller:
namespace MySite.Controllers
{
public class ContentPagesController : Controller
{
readonly IContentPagesRepository _contentPagesRepository;
public ContentPagesController()
{
MyDBEntities entities = new MyDBEntities();
_contentPagesRepository = new SqlContentPagesRepository(entities);
}
public ActionResult Index(string name)
{
var contentPage = _contentPagesRepository.GetContentPage(name);
if (contentPage != null)
{
return View(new ContentPageViewModel
{
ContentPageId = contentPage.ContentPageID,
Name = contentPage.Name,
Title = contentPage.Title,
Content = contentPage.Content
});
}
throw new HttpException(404, "");
}
}
}
And in my global.asax:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Page", // Route name
"Page/{name}", // URL with parameters
new { controller = "ContentPages", action = "Index" }, // Parameter defaults
new[] { "MySite.Controllers" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new[] { "MySite.Controllers" }
);
}
So I have a dynamic page in my database, named About. If I go to mysite.com/Page/About, I can view the dynamic content.
I want to create an ActionLink to this page. I've tried it like this:
#Html.ActionLink("About Us", "Index", "ContentPages", new { name = "About" })
But when I look at the link on the page, the url just goes to the current page with Length=12 in the query string. For instance, if I'm on the homepage, the link goes to mysite.com/Home?Length=12
What am I doing wrong here?
You are not using the correct ActionLink overload. Try like this:
#Html.ActionLink(
"About Us", // linkText
"Index", // action
"ContentPages", // controller
new { name = "About" }, // routeValues
null // htmlAttributes
)
whereas in your example:
#Html.ActionLink(
"About Us", // linkText
"Index", // action
"ContentPages", // routeValues
new { name = "About" } // htmlAttributes
)
which pretty obviously explains why your doesn't generate the expected link.
I am building an asp.net mvc website, after the user login he can access his profile section pages and currently these pages URL is like that www.example.com/profile , what I want is to make the URL like that www.example.com/USERNAME
How to write this route which will work just in profile page when the user login?
Update:
based on the answers below, I wrote it like this:
routes.MapRoute(
"AccountSettins",
"AccountSettings",
new { controller = "AccountSettings", action = "Index" }
);
routes.MapRoute(
"myRouteName",
"{username}",
new { controller = "Profile", action = "Index" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
and the controller:
[Authorize]
public class ProfileController : BaseController
{
//
// GET: /Profile/
public ActionResult Index(string username= "")
{ ...
But now after the user login and his user name was "xyz" he can go to www.example.com/xyz and this will lead to the profile page, but if he also wrote the url www.example.com/abc he will go to the same profile page normally which is something strange from the user point of view, how to solve this issue?
In your Global.asax...
routes.MapRouteWithName(
"routeUserProfile",
"{username}",
new { controller = "User", action = "Profile", username = "" });
In your User controller....
public ActionResult Profile(string username) {
//conditional logic to check if username is user
// render user profile with special user-only stuff
//else
// render only generic stuff about user
}
routes.MapRoute(
"myRouteName",
"{username}",
new { controller = "Home", action = "Profile" }
);
You can specify you controller and action you want and just use the username for your parameter for the method Profile of the Home class.
You will need to write a controller specifically for this and create a route like:
routes.MapRoute(
"UserPage", // Route name
"{username}", // URL with parameters
new { controller = "User", action = "Index", username = ""} // Parameter defaults
);
See here for more details:
http://dotnet.dzone.com/articles/aspnet-mvc-routing-basics?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+zones%2Fdotnet+(.NET+Zone)
In the global.asax file add the following routes
routes.MapRoute(
"UsersRoute", // Route name
"{username}", // URL with parameters
new { controller = "Test", action = "Index", username = "" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
And according to the first route add the following controller as bellow
public class TestController : Controller
{
public ActionResult Index(string username )
{
var p = username;
return View();
}
}
To prevent user to see others profile, just check in the action if he/she can do that.
public ViewResult Index(string username)
{
if (CanSeeOthersProfiles(username)) //your function to check currently logged user and his privileges
{
var model = new MyModel();
//do your logic
return View(model);
}
else
return RedirectToAction("index", "home");
}