I developed a website with MVC and I have a little problem on how link addresses appears in the address bar.
When I open the website, I have to log on first; after I log on into the account, the home page appear, but in the browser address bar I still have
http://localhost:1413/Account/LogOn
instead of
http://localhost:1413/Home
Also, after I log out, I am redirected to the log in page, but in the address bar it appears
http://localhost:1413/Account/LogOn
I would like to be just
http://localhost:1413/Account/LogOff
My Global.asx code
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 = UrlParameter.Optional } // Parameter defaults
);
}
I used this type of redirection, but the result is the same:
public ActionResult LogOn()
{
if (HttpContext.User.Identity.IsAuthenticated == true)
{
return RedirectToAction("Index", "Home");
}
return View();
}
you need to use redirect action to home page like this
RedirectToAction("Action", "Controller")
so when user has been authenticated you need to redirect the user to the particular controller.
Same goes for the when user logged off
As I can see, your problem is not the routing cause your routing is working fine. Your problem is that you work in the controller Account. That's why account always appears in you url. If you want to get this:
http://localhost:1413/Home
You must link to a controller which you called HomeController.cs
I hope you understand what i tried to explain.
Maybe this can help you more:
http://www.codeproject.com/Articles/190267/Controllers-and-Routers-in-ASP-NET-MVC-3
Related
This may be a simplest question, but I am faced with the following issue.
I have a project, and have the login view at http://localhost/Some.Web/Login/Index. If I type http://localhost/Some.Web/ I want to redirect it to login page. At the moment I am getting the "The resource cannot be found." error message. My route config has the following entry.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
);
What am I doing wrong. Open to suggestions.
there are two ways you can set custom routes like [routre("your route")]
when you set this the add this in your route.
routes.MapMvcAttributeRoutes(); to the routeconfig.cs file
and there is another way in your controller check if the user is authorize the redirect to that page other wise redirect to login page
if(userIsValid)
{
redirect("main page here")
}
else{
redirect("login page here")
}
I would like to create link on my site, which, after click, would open download window (just some simple text file). In several tutorials I found a way to do it, however, for some reason, it seems that ActionLink doesnt call my method and looks for a view instead
My ActionLink
#Html.ActionLink("here is the gpx log", "Download", "Treks")
My Download method in Treks controller (added also following method using attribute routing in case it the case of the mess)
public FileResult Download()
{
byte[] fileBytes = System.IO.File.ReadAllBytes(#"~/Files/file.txt");
string fileName = "file.txt"; //I will add parameters later, once the basics work
return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}
[Route("treks/{trekname}")] //Route: /Users/12
public ActionResult ShowTrek(string trekname)
{
return View(trekname);
}
And this is the error I always get
The view 'Download' or its master was not found or no view engine supports the searched locations. The following locations were searched..
~/Views/Treks/DownloadFiles.aspx blahblahbla:
I spent one hour working on this and still not an inch closer to the solution. Does anybody know where I am making a mistake? Thanks a lot
Update: This is the content of my RouteConfig file
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Edit: Ok, I debugged it. Seems the problem is in attribute routing. For some reason, controller ignored Download method and goes directly for ActionResult ShowTrek... any idea how to fix it?
Try to replace Fileresult with FileStreamResult
you may also need to create filestream object inside your method
new FileStream(fileName, FileMode.Open)
public FileStreamResult Download()
{
// Your code
}
Solved. Problem was in attribute routing. Pls see answer of Stephen Muecke in comments
I usually get the url from a node with the following code:
MvcSiteMapProvider.SiteMaps.Current.FindSiteMapNodeFromKey("AccountDetailsKey").Url
Now I have a node with a parameter. But how can I get the url for that node. So in the below example we need the url of the "AccountDetailsKey" node.
<mvcSiteMapNode key="BeherenAccountKey" title="Zoeken accounts" controller="BeherenAccount" action="BeherenAccount">
<mvcSiteMapNode key="AccountDetailsKey" title="Account details" controller="BeherenAccount" action="AccountDetails" preservedRouteParameters="gebruikersnaam" visibility="!SiteMapHelper,!MainMenu,*" />
</mvcSiteMapNode>
Details action:
[Route("account/details/{gebruikersnaam}")]
public ActionResult AccountDetails(string gebruikersnaam)
{
return this.View((object)gebruikersnaam);
}
De routeconfig:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}
Offcourse we could use the following for generating an url to the details page with regular MVC razor code:
#Url.Action("AccountDetails", "BeherenAccount", new { gebruikersnaam = User.Identity.Name.ToLower().Replace("domain\\", "") })
The thing is that we don't want to use action and controller names in our code. We want to generate all the urls from the sitemap. Everything works fine in the whole application but can't get this details page working. We don't have a DynamicNodeProvider because we don't care for separate titles, seo etc because it is an administrator application.
The application shows the loggedin user in the main menu (_Layout page) and this is an url to his own detail page.
So when the loggedin user has username "abc", the details url must be "account/details/abc".
When using preservedRouteParameters, the SiteMap does not automatically generate the route values that are supposed to be placed onto the node. They come from the current request of the page. Normally, when doing this you are expected to provide URLs using ActionLink, Action, RouteLink, or UrlHelper, as would typically be the case when doing CRUD operations, since the links would need to be derived from the database data.
#Html.ActionLink("Gebruikersnaam", "AccountDetails", "BeherenAccount", new { gebruikersnaam = "Value" }, null)
Alternatively, if no route value named gebruikersnaam exists in the current request, you can supply it manually.
string url;
var node = MvcSiteMapProvider.SiteMaps.Current.FindSiteMapNodeFromKey("AccountDetailsKey");
if (node != null)
{
node.RouteValues["gebruikersnaam"] = "Value";
url = node.Url;
}
When you set a route value outside of an ISiteMapNodeProvider or dynamic node provider, the value that is set will only last for the lifetime of the current request.
NOTE: I really don't understand the exact problem you are having with the above code. In my test project it is working fine regardless of what page you are on. If you want to investigate further, you can use the code from Controlling URL Behavior to mimic how the SiteMapNodeUrlResolver uses the MVC UrlHelper.
I have come across the most bizarre of problems: I have a login page in an MVC application, which when linked by /login will automatically redirect to the home page. However, if I use /Login or /login/, it works!
I have no idea whether it's something to do with a configuration I've messed up, or a configuration in the routing I've played around with, but it happens exclusively with the login page.
I am using forms authentication, and have tried changing the page that you're redirected to from the login page, but that doesn't seem to help at all.
Any ideas?
Update: this only happens on my local machine. I host with Windows Azure, and it works fine when deployed.
Edit: current routing configuration:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Index", action = "Index", id = UrlParameter.Optional }
);
routes.LowercaseUrls = true;
}
I have a User area and inside this I have the following registered:
context.MapRoute("DefaultRedirect",
"",
new { controller = "Account", action = "Login" }
);
When I use routeDebug it tells me that when I connect to my site www.xxx.com then it will try to call
area = User, controller = Account, action = Login
When I connect directly using: www.xxx.com/User/Account/Login my login page appears.
When I don't use routeDebug and connect to my site www.xxx.com then I get an error message saying:
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /
Here's my controller action method:
public class AccountController : Controller
{
//
// GET: /Account/Login
[AllowAnonymous]
public ActionResult Login()
{
ViewBag.ReturnUrl = "xx";
return View("~/Areas/User/Views/Account/Login.cshtml");
}
I am very confused as routeDebug appears to show I am going to the right controller and action however when I don't use that and place a breakpoint it does not seem to go to the controller action.
if this controller is inside the same area i think you just can use
[AllowAnonymous]
public ActionResult Login()
{
ViewBag.ReturnUrl = "xx";
return View();
}
Either way if you have only the views on a different areas you can use
return View("~/Views/YourArea/YourController/YourView.aspx");
return RedirectToAction("Login", "Account");
Will redirect to specific controller and specific action.
If account is deeper in folders just include the path