I have created a controller called loginController.cs and i have created a view called login.aspx
How do I call that view from loginController.cs?
The ActionResult is always set to index and for neatness, I want to specify what view the controller uses when called rather than it always calling its default index?
Hope that makes sense.
You can customize pretty much everything in MVC routing - there is no particular restriction on how routes look like (only ordering is important), you can name actions differently from method names (via ActionName attribute), your can name views whatever you want (i.e. by returning particular view by name).
return View("login");
In the interest of actually answering the question.. you can add a route ABOVE your default route in Global.asax:
routes.MapRoute(
"SpecialLoginRoute",
"login/",
new { controller = "Login", action = "Login", id = UrlParameter.Optional }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
..although, without properly thinking through what you're trying to achieve (that being.. changing what MVC does by default) you're bound to end up with lots and lots of messy routes.
Your return the view from your controller via your Action methods.
public class LoginController:Controller
{
public ActionResult Index()
{
return View();
//this method will return `~/Views/Login/Index.csthml/aspx` file
}
public ActionResult RecoverPassword()
{
return View();
//this method will return `~/Views/Login/RecoverPassword.csthml/aspx` file
}
}
If you need to return a different view (other than the action method name, you can explicitly mention it
public ActionResult FakeLogin()
{
return View("Login");
//this method will return `~/Views/Login/Login.csthml/aspx` file
}
If you want to return a view which exist in another controller folder, in ~/Views, you can use the full path
public ActionResult FakeLogin2()
{
return View("~/Views/Account/Signin");
//this method will return `~/Views/Account/Signin.csthml/aspx` file
}
Related
I am getting results based on an ID which is passed into the controller via the URL, for example Site/View/12 - this will bring back all results that match 12.
However, if there are no results, I want to re-direct back to the Index page which also has the search field.
public new ActionResult View(string ID = "")
{
XDocument xml = XDocument.Load(xmlPath);
var bikes = (xml).ToList();
if (!bikes.Any())
{
return RedirectToAction("Index", "Home");
}
else
{
return View(bikes);
}
}
However, whilst trying to view any page (/Add, /Index etc) I get a "This webpage has a redirect loop" error.
I'm not quite sure what's going on, because as far as I can tell viewing these pages shouldn't even trigger anything inside ActionResult View(). Also, the RedirectToAction is going to Index - so I cannot figure out where the loop is.
If I remove the line return RedirectToAction("Index", "Home"); the application functions normally.
Any advice would be very welcome, thank you.
(edit) Here's the Index controller:
public ActionResult Index()
{
return View();
}
And here's the RouteConfig.cs file:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
The controller has a View method to return the view, but your Action method is also named View, and that's where it gets stuck. Change your action to be:
[ActionName("View")]
public new ActionResult ViewItem(string ID = "")
And everything should work OK.
Your action is named View. When you do
public ActionResult Index()
{
return View();
}
it's defaulting to your method (the optional parameter makes it valid):
public new ActionResult View(string ID = "")
If you mouseover return View() intellisense will tell you which View() its calling. Rename your View action and you'll see that the intellisense changes which View() is referenced, and it should work fine. Using an attribute to keep your action as View seems like its just going to cause another confusing headache later.
I need my page names to have a dash in the name. E.G our-vision
I'm new to MVC & c# so I may be going about all this wrong.
Here is my controller:
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
//
// GET: /our-vision/
public ActionResult ourVision()
{
return View();
}
}
And then in my views, I have Views/Home/ourVision.cshtml.
When I compile and go to http://localhost/ourVision it works, but when I go to http://localhost/our-vision it does not.
Here is my routing:
routes.MapRoute(
"Default", // Route name
"{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
You'll need to do a few things in order to achieve that.
First, to achieve our-Vision, you'll need to give your action method the ActionName attribute, like so:
[ActionName("our-Vision")]
public ActionResult ourVision()
Next, you'll have to rename your ourVision.cshtml view to be our-Vision.cshtml
Finally, whenever you're using Url.Action or ActionLink, you need to use our-Vision and not vision, like so:
Url.Action("our-Vision", "Home");
IMHO
The best way to do this - is define new route in route engine:
routes.MapRoute(
"OurVision", // Route name
"our-vision", // URL with parameters
new { controller = "Home", action = "ourVision" } // Parameter defaults
);
I know you can pass in parameters via urls like .com/MyPage/?controlID=5 but how can you do it with something like .com/MyPage/5? Thus not requiring the variable name or a question mark.
You would define a custom route, or use the model binding to get the intended effect. In your case, the route would be something like:
routes.Add("someRoute",
"{controller}/{action}/{controlId}",
new { controller = "Home", action = "Index", controlId = UrlParameter.Optional }
);
public ActionResult Index(int? controlId)
{
}
Now, the only "gotcha" with this route is that if you also have the default route specified, these two routes will be in contention and the first one you have defined will win. If there is some form of differentiating value (say, that controlId always matches some kind of pattern), then you can always add a HttpRouteConstraint to the route to differentiate your new route from the default route.
Alternatively, you can rename the parameter on your action method, if you are still using the default route, to be id, and change your query string key to 'id':
public ActionResult Index(int? id)
{
// Do Stuff
}
Create a method in MyPageController:
public ActionResult Index (int id)
{
}
That will work with the default routes
I am working on an ASP.NET MVC application. For some reason, everytime I think I understand routing, something pops up that I don't understand. Currently, I have two routes that I can't seem to figure out. My directory structure looks like the following
- Views
- Internal
- Profile
- Index.cshtml
- Input
- Page1.cshtml
In my global.asax.cs file, I have added the following mappings:
routes.MapRoute(
"UserProfileInfo",
"{controller}/profile",
new { controller = "Internal", action = "UserProfileInfo" }
);
routes.MapRoute(
"Page1",
"{controller}/input/page1",
new { controller = "Internal", action = "Page1" }
);
In MyController, I have the following:
public ActionResult UserProfileInfo()
{
return View("~/Views/internal/profile/Index.cshtml");
}
public ActionResult Page1()
{
return View("~/Views/internal/input/Page1.cshtml");
}
I want to store my actions in a single controller. I thought I had everything setup properly. But I continue to get a 404. What am I doing wrong?
Remove the "Controller" suffix from the controller name in your calls to MapRoute to create a mapping to a class called InternalController. The Controller suffix is appended by the framework when looking for a matching implementation. e.g.:
routes.MapRoute(
"UserProfileInfo",
"{controller}/profile",
new { controller = "Internal", action = "UserProfileInfo" }
);
I have multiple controllers with different actions (no "Index" actions). The actions I consider "default" actions, are named differently. I want to create default routes for their names and have the first available action (from my list of default actions) executed if only the controller name is provided in the route.
So, for example, I have the following actions which I want to consider default and want checked for their existence in a controller in this order:
List()
Draw()
ViewSingle()
The routing should somehow search for /{controller} and then take the first available action from the list above as default action, e.g.:
/ControllerA -> ControllerA.List()
/ControllerB -> ControllerB.Draw()
/ControllerC -> ControllerC.ViewSingle()
/ControllerD -> ControllerD.Draw()
/ControllerE -> ControllerE.List()
Is this possible? I tried creating additional Default actions like this but couldn't get it to work:
routes.MapRoute("Default1", "{controller}/{action}",
new { controller = UrlParameter.Optional, action = "List" }
routes.MapRoute("Default2", "{controller}/{action}",
new { controller = UrlParameter.Optional, action = "Draw" }
routes.MapRoute("Default3", "{controller}/{action}",
new { controller = UrlParameter.Optional, action = "ViewSingle" }
Help?
I think you got something wrong about the default route. Those controller and action parameters are there for convention. If URL has a controller name in it, it will route to suitable controller. Same thing is true for Index methods. It just provides a default value for that.They are already optional and that's why. I think you don't need routes here: You could try to place your default functions in Index methods and it would work.Just to be clear:
public class ControllerA:Controller
{
public ActionResult Index()
{
return List();
}
public ActionResult List()
{
//List function
}
}
public class ControllerB:Controller
{
public ActionResult Index()
{
return Draw();
}
public ActionResult Draw()
{
//Draw function
}
}
I think it would work. But if you want to go on with creating routes, you create each route like this:
routes.MapRoute("Default1", "ControllerA",
new { controller = ControllerA, action = "List" }
Notice that ControllerA is not in curly braces,it's a static text. So you create routes for each controller. Keep controller naming convention in mind.
I agree with Narsil. You should write a constant to url. -like controller name- 'cause MVC cannot resolve this routes and cannot figure out what you want to show.
eg.
routes.MapRoute(null, "ControllerA/{action}",
new { controller = "ControllerA", action = "List" }
routes.MapRoute(null, "ControllerB/{action}",
new { controller = "ControllerB", action = "Draw" }
routes.MapRoute(null, "ControllerC/{action}",
new { controller = "ControllerC", action = "ViewSingle" }