I have some dynamic user route like
routes.MapRoute(
"UserNames", // Route name
"{username}", // URL with parameters
new { controller = "Home", action = "UserName" });
and under the HomeController.cs
public ActionResult UserName(string username)
{
ViewBag.Message = username;
return RedirectToAction("Register","Account"); // Test...
}
It is working fine.
But what I need is to get working the URL like
http:\\mywebsite.com\UserNameBob\MyGallery\1
http:\\mywebsite.com\UserNameBob\Profile
http:\\mywebsite.com\UserNameBob\MyFriends
How do I can archive it?
Any clu?
Thank you!!!
Do you mean something like this:
routes.MapRoute(
"UserNames", // Route name
"{username}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "UserName", id = UrlParameter.Optional });
And then in HomeController you put actions like these:
public ActionResult MyGallery(string username, int id) {
// code
}
public ActionResult Profile(string username) {
// code
}
EDIT: Of course, if the gallery ID is not an int, just use string or whatever is appropriate.
Look for URL Rewriting in ASP.NET to handle the dynamic parameters while routing.
Related
When a user chooses one profile to log in with, I want the name of the profile appear in the url, like this: http://localhost:1234/Bryan
I have this in my Route:
routes.MapRoute(
"Home",
"{username}",
new { controller = "Home", action = "index", username = "" });
Here is my Home-controller:
public ActionResult Index(string username)
{
if (Request.Cookies["ProfileId"] != null)
{
return View(homeIndexModel);
}
return RedirectToAction("Index", "ProfileLogin");
}
My question Is: how do I pass the username to the URL from here? I want it to be in the format: http://localhost123/Bryan, not http://localhost123/Home/Index/Bryan
I don't know how to make It appear in the URL.
Basically I have a CMS backend I built using ASP.NET MVC and now I'm moving on to the frontend site and need to be able to load pages from my CMS database, based on the route entered.
So if the user enters example.com/students/information, MVC would look in the pages table to see if a page exists that has a permalink that matches students/information, if so it would redirect to the page controller and then load the page data from the database and return it to the view for display.
So far I have tried to have a catch all route, but it only works for two URL segments, so /students/information, but not /students/information/fall. I can't find anything online on how to accomplish this, so I though I would ask here, before I find and open source ASP.NET MVC CMS and dissect the code.
Here is the route configuration I have so far, but I feel there is a better way to do this.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Default route to handle core pages
routes.MapRoute(null,"{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new { controller = "Index" }
);
// CMS route to handle routing to the PageController to check the database for the route.
var db = new MvcCMS.Models.MvcCMSContext();
//var page = db.CMSPages.Where(p => p.Permalink == )
routes.MapRoute(
null,
"{*.}",
new { controller = "Page", action = "Index" }
);
}
If anybody can point me in the right direction on how I would go about loading CMS pages from the database, with up to three URL segments, and still be able to load core pages, that have a controller and action predefined.
You can use a constraint to decide whether to override the default routing logic.
public class CmsUrlConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
var db = new MvcCMS.Models.MvcCMSContext();
if (values[parameterName] != null)
{
var permalink = values[parameterName].ToString();
return db.CMSPages.Any(p => p.Permalink == permalink);
}
return false;
}
}
use it in route definition like,
routes.MapRoute(
name: "CmsRoute",
url: "{*permalink}",
defaults: new {controller = "Page", action = "Index"},
constraints: new { permalink = new CmsUrlConstraint() }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Now if you have an 'Index' action in 'Page' Controller like,
public ActionResult Index(string permalink)
{
//load the content from db with permalink
//show the content with view
}
all urls will be caught by the first route and be verified by the constraint.
if the permalink exists in db the url will be handled by Index action in Page controller.
if not the constraint will fail and the url will fallback to default route(i dont know if you have any other controllers in the project and how you will decide your 404 logic).
EDIT
To avoid re querying the cms page in the Index action in Page controller, one can use the HttpContext.Items dictionary, like
in the constraint
var db = new MvcCMS.Models.MvcCMSContext();
if (values[parameterName] != null)
{
var permalink = values[parameterName].ToString();
var page = db.CMSPages.Where(p => p.Permalink == permalink).FirstOrDefault();
if(page != null)
{
HttpContext.Items["cmspage"] = page;
return true;
}
return false;
}
return false;
then in the action,
public ActionResult Index(string permalink)
{
var page = HttpContext.Items["cmspage"] as CMSPage;
//show the content with view
}
I use simpler approach that doesn't require any custom router handling.
Simply create a single/global Controller that handles a few optional parameters, then process those parameters as you like:
//Route all traffic through this controller with the base URL being the domain
[Route("")]
[ApiController]
public class ValuesController : ControllerBase
{
//GET api/values
[HttpGet("{a1?}/{a2?}/{a3?}/{a4?}/{a5?}")]
public ActionResult<IEnumerable<string>> Get(string a1 = "", string a2 = "", string a3 = "", string a4 = "", string a5 = "")
{
//Custom logic processing each of the route values
return new string[] { a1, a2, a3, a4, a5 };
}
}
Sample output at example.com/test1/test2/test3
["test1","test2","test3","",""]
I want to be able to handle any url that s requested via some controller.
foo.com/a
foo.com/abcd
foo.com/x1
for foo.com/a
I want to process it with
UrlHandlerController with Process(string url) method.
How should i add a routing rule to be able to do this?
Any ideas?
Create a new custom route and use Phill Haack's Route Debugger to test your routes:
routes.MapRoute(
"customroute",
"{url}",
new { controller = "UrlHandler",
action = "Process",
url = ""
}
);
Controller:
public class UrlHandlerController : Controller
{
[HttpGet]
public ActionResult Process(string url)
{
return View();
/* or */
if(url == "something"){
return View("SomethingView");
}
else if(url == "somethingelse"){
return View("SomethingElseView");
}
}
}
Darth, see if this route helps:
routes.MapRoute(
"CustomRoute", // Route name
"{url}", //Route formation
new { controller = "UrlHandler", action = "Process" }, // Where to send it
new { keyWord = #"\S+" } // Regex to identify the argument
);
Regards.
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");
}
I'm trying to read the a parameter that I've defined in a route from inside the controller.
The route:
routes.MapRoute(
"BusinessVoice", // Route name
"business/{controller}/{action}/{id}", // URL with parameters
new { controller = "Voice", action = "Index",
id = UrlParameter.Optional, locale = "business" } // Parameter defaults
);
From inside the controller I'd like to be able to read the route parameter locale, but have not idea where to look for it.
The controller:
namespace www.WebUI.Controllers
{
public class VoiceController : Controller
{
public VoiceController()
{
... want to read the locale param here
}
public ViewResult Index(string locale)
{
return View();
}
}
}
Any help is appreciated!
Dave,
This is from my basecontroller but you should be able to do exactly the same from a top level one too:
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
var locale = requestContext.RouteData.Values["locale"].ToString() ?? System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;
base.Initialize(requestContext);
}
good luck
jim
public VoiceController()
{
var locale = this.RouteData.Values["locale"];
}