How to get the profile name In the URL - c#

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.

Related

Asp MVC URL doesn't redirect to index after successful authentication

In my ASP MVC web application, when I try to authenticate using email and password to log in. The URL redirect doesn't allow me to pass to the main page after successful authentication.
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
if (!string.IsNullOrWhiteSpace(returnUrl) && Url.IsLocalUrl(returnUrl) && returnUrl.Contains(nameof(windowsLogOff)))
{
return RedirectToAction(nameof(Login));
}
if (User.Identity.IsAuthenticated)
{
return RedirectToAction(nameof(windowsLogOff), new { returnUrl = returnUrl });
}
if (OwinAuthentication.AuthenticationTypes._ActiveAuthenticationsList.Count == 1 && Portal.Commons.Models.Configuration.ByPassAuthentication)
{
return RedirectToAction(nameof(ExternalLoginRedirect), new { returnUrl = returnUrl, provider = OwinAuthentication.AuthenticationTypes._ActiveAuthenticationsList[0].AuthenticationTypeDefault });
}
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
[AllowAnonymous]
public ActionResult Login(LoginViewModel model)
{
if (ModelState.IsValid)
{
using (var db = new appDbContext())
{
var encodedPWD = Sha256(model.Password);
var obj = db.Users.Where(a => a.Email.Equals(model.Email) && a.PasswordHash.Equals(encodedPWD)).FirstOrDefault();
if (obj != null)
{
Session["id"] = obj.Id.ToString();
Session["name"] = obj.name.ToString();
Session["email"] = obj.Email.ToString();
return RedirectToAction("Manager", "home");
}
ModelState.AddModelError("", "Email or Password is invalid!.");
}
}
return View(model);
}
and my routeConfig code:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "DefaultEn",
url: "en/{controller}/{action}/{id}",
defaults: new { language = "en", controller = "data", action = "index", id = UrlParameter.Optional },
constraints: new { controller = "data" },
namespaces: new[] { "Portal.Controllers" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
When I enter on login page the URL on localhost is something like this:
http://localhost:3535/account/login?ReturnUrl=%2F
When I fill the login form with the correct credentials I got this:
http://localhost:3535/account/login?ReturnUrl=%2Fhome%2FManager
Instead of:
http://localhost:3535/account/Manager
About OwinAuthentication, using external login to authenticate such as Google and Microsoft, both works without any issue, I only got a problem on manual login.
I have found that the solution to solve this issue is creating a Custom Authentication and Authorization for my custom local login.
My custom login only updates session and redirects to account/index, which probably requires authentication, thus the redirect to the authentication url.

Handle Multiple action with same name in MVC

In my project there is an action
public ActionResult Lead(int leadId)
{
return View();
}
and in the View an ActionLink was created like this
#Html.ActionLink("Old Link", "Lead", "Home", new { leadId = 7 }, null)
But after some time, to make clean URL, I have changed the name of parameter of that action
public ActionResult Lead(int id)
{
return View();
}
And ActionLink change accordingly
#Html.ActionLink("New Link", "Lead", "Home", new { id = 5 }, null)
But old link was shared in multiple social network sites. Whenever anyone clicks on that old link, he is redirect to the page www.xyx.com/Home/Lead?leadId=7
But now in my application, no such URL exists.
To handle this problem, I was thinking of overloading, but MVC action doesn't support overloading.
I have created another Action with same name with extra parameter, and redirect to new action, but it doesn't work.
public ActionResult Lead(int leadId, int extra=0)
{
return RedirectToAction("Lead", "Home", new { id = leadId });
}
I have found one link to handle such situation, but It is not working in my case.
ASP.NET MVC ambiguous action methods
One possibility to handle this would be to write a custom route:
public class MyRoute : Route
{
public MyRoute() : base(
"Home/Lead/{id}",
new RouteValueDictionary(new
{
controller = "Home",
action = "Lead",
id = UrlParameter.Optional,
}),
new MvcRouteHandler()
)
{
}
public override RouteData GetRouteData(HttpContextBase httpContext)
{
var rd = base.GetRouteData(httpContext);
if (rd == null)
{
return null;
}
var leadId = httpContext.Request.QueryString["leadid"];
if (!string.IsNullOrEmpty(leadId))
{
rd.Values["id"] = leadId;
}
return rd;
}
}
that you will register before the default one:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add(new MyRoute());
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
and now you could only have a single action:
public ActionResult Lead(int id)
{
return View();
}
Now both the following urls will work as expected:
www.xyx.com/Home/Lead/7
www.xyx.com/Home/Lead?leadId=7

MVC routing only applying to certain action results

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!

Route to user's page under the dynamic username path in MVC4

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.

how to write a route which include the username

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");
}

Categories

Resources