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");
}
Related
How do I map unmatched routes to the index action for that controller?
I'm using a client side router for routes like /Home/foo
routes.MapRoute(
name: "Test",
url: "{controller}/{*.}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
This currently results in a 404.
Your route that you used is correct, the problem is the orders of the routes that need to be added in write format:
for example if you have some routes like:
routes.MapRoute(
name: "PreTest",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Test",
url: "{controller}/{*.}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
So it is always matched with first route PreTest. Check your routes order. It is work like a dictionary that ordered. Check this for more information.
I would create an AuthorizeAttribute to handle your case. Then you can decorate your controller with that attribute.
Here's a small example to redirect your action base on a value in the route:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class RedirectAttribute:ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if(filterContext.Controller.ControllerContext.RouteData.Values.ContainsValue("Foo"))
{
//Redirect to the login for example
UrlHelper urlHelper = new UrlHelper(filterContext.HttpContext.Request.RequestContext);
string url = urlHelper.Action("actionName", "controllerName");
filterContext.Result = new RedirectResult(redirectUrl);
}
}
}
Here's how to use it in a controller:
[Redirect]
public class MyCustomController : AsyncController
{
public ActionResult Index()
{
return View();
}
public ActionResult Foo()
{
//It will redirect
return View();
}
}
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.
Hey Guys I have easy problem, I want to change start page.
In HomeControllers.cs I have:
public ActionResult Index()
{
if (Session["LoginId"] == null)
{
return RedirectToAction("Login.aspx");
}
return View();
}
It redirects to: http://localhost/TutorialCS/Home/Login.aspx
But I want to get rid off the /Home
When in Global.asax.cs I change;
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
to one without {Controller}:
routes.MapRoute(
"Default", // Route name
"{action}/{id}", // URL with parameters
new { action = "Index", id = "" } // Parameter defaults
);
It redirects to correct repository, but page dosen't work anymore I suppose this changes a lot of paths.
RedirectToAction has another overload that accepts controller name as the second parameter:
protected internal RedirectToRouteResult RedirectToAction(
string actionName,
string controllerName
)
So:
return RedirectToAction("Login", "Account");
Update: If you want to redirect to this URL:
http://localhost/TutorialCS/Login.aspx
You should use Redirect method:
return Redirect("~/TutorialCS/Login.aspx");
You just need to use method call with two parameters: Action name and Controller Name:
RedirectToAction("Login", "Account")
Do I have to route a special route for every action result in a controller, or do you do one route, and have to live by that standard thought the controller? I thought you could make a default route, and then a special route for any instance you wanted. I keep running into a problem where one of my routes will hit my action Results correctly, but then the others no longer work. This code is probably the wrong way, but hence why I am posting it here. PLease try to clarify this for me if you can. I understand that I am suppose to be able to do {controller}/{action}/{id} for example. So that should hit Settings/GetSite/{siteid} for the following
public ActionResult GetSite(int id);
Routes configuration:
routes.MapRoute(
"SettingsUpdateEnviorment",
"{controller}/{action}",
new { controller = "Settings", action = "UpdateProperties" },
new { httpMethod = new HttpMethodConstraint("POST") }
);
routes.MapRoute(
name: "ProfileRoute",
url: "Profiles/{userId}",
defaults: new
{
controller = "Profile",
action = "Index",
}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
"Settings", // Route name
"Settings/{id}", // URL with parameters
new { controller = "Settings", action = "Index" } // Parameter defaults
);
Controller Code:
public ActionResult Index(int id)
{
return View(model);
}
public ActionResult GetSite(int enviornmentID, string name)
{
return RedirectToAction("Index");
}
[HttpPost]
public ActionResult AddSite(int id)
{
return RedirectToAction("Index", new { id = id });
}
So, the URL works as expected for Settings/1 to hit the Index actionresult Index(int id). Then, when I try to do the ActionResult for GetSite(int enviornmentID, string name) using the following actionLink:
#Html.ActionLink(site.Name, "GetSite", "Settings", new { enviornmentID = Model.Enviorment.EnvironmentID, name = site.Name }, null)
It creates the URL correctly as follows: Settings/GetSite?enviornmentID=1&name=CaseyTesting2, but gives me an error stating that I am trying to send a null value to my Index(int id) actionResult. I thought that since I am using the action name and it's same params, that MVC will figure the route out? Why is this not functioning for me, or what I am doing wrong? Thanks!
I realized what I was doing thanks to this article http://www.itworld.com/development/379646/aspnet-mvc-5-brings-attribute-based-routing. I was mixing up the order, when I had everything else correct. Then I was missing the param names being identical, when everything else was correct. So I kept having minor issues when trying to find the problem out. I also switched to MVC5's attribute routing, and like it much more.
So this is my code that is now working:
RoutConfig
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "ProfileRoute",
url: "Profiles/{userId}",
defaults: new
{
controller = "Profile",
action = "Index",
}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
The controller code
[Authorize]
[RoutePrefix("settings")]
[Route("{action=index}")]
public class SettingsController : ZenController
{
[Route("{id:int}")]
public ActionResult Index(int id)
{
return View(model);
}
[Route("GetSite/{sitename:alpha}")]
public ActionResult GetSite(string sitename)
{
return RedirectToAction("Index");
}
Thanks again everyone! Happy coding!
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.