I am developing an application in asp.net using mvc4. I am very new to asp.net. Following is my global.asax code
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Default", action = "Index",
id = UrlParameter.Optional }
);
}
Also
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
Also I am having a controller named Default1Controller, which has a action method named MyAction. On the click of button I want this Method to get executed. But while debugging the control does not come here i.e the method does not gets invoked. Following is my controller code
public class Default1Controller : Controller
{
//
// GET: /Default1/
public ActionResult Default1()
{
return View();
}
public ActionResult MyAction()
{
return View();
}
}
Also following is the cshtml
#{
ViewBag.Title = "Default1";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Default1</h2>
<div>
<p>Welcome to the world of MVC!!!!</p>
<div>
<input type="button" value="Click Me"
onclick="window.location.href('#Url.Action("MyAction","Default1Controller")')" />
</div>
</div>
On clicking on the button, this is the error that i get
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: /Default1Controller/MyAction
Can anyone tell me where
I am going wrong. Any help will be highly appreciated. Also I would like to add that I am using VS 2010. .Net 4.0.
Thanks and Regards
Try below code
<input type="button" value="Click Me" onclick="window.location.href('#Url.Action("MyAction","Default1")')" />
You do not need to include 'Controller' as part of the controller name when using Url.Action(), this applies anywhere where you pass in the controller name as a string:
Also, window.location.href is not a function so should be set using =.
This should load to the correct action:
<input type="button" value="Click Me" onclick="window.location.href = '#Url.Action("MyAction","Default1")'" />
window.location.href is a property instead of a method, so you should change the code like this :
onclick="window.location.href = '#Url.Content("~/Default1/MyAction")';"
Related
Edited the question as I've found out that the issue isn't inside the razor, but instead in the route
I have a very simple login form, but somehow, when the user presses Login the page goes tot Error404 and it simply does not hit the controller breakpoints for some reason.
#using (Html.BeginRouteForm("MyCustomRoute", new { controller = "login", action = "verify", FormMethod.Post }))
{
<fieldset class="clearfix">
<p><span style="float:none;color:black; font-size:20pt;"></span></p>
<p><span style="float:none;color:black; font-size:20pt;"></span></p>
<p><span class="fa fa-user"></span>#Html.TextBoxFor(m => m.UserName, new { #class = "form-control", placeholder = "Username", onkeydown = "convertTabtoEnter(this, event)", autofocus = "" })</p> <!-- JS because of IE support; better: placeholder="Username" -->
<p>
<span class="fa fa-lock"></span>#Html.PasswordFor(m => m.Password, new { #class = "form-control", placeholder = "Password", onkeyup = "convertTabtoEnter()" })
</p> <!-- JS because of IE support; better: placeholder="Password" -->
<div>
<span style="width:48%; text-align:left; display: inline-block;">
<a class="small-text" href="#">
#*Forgot
password?*#
</a>
</span>
<span style="width:50%; text-align:right; display: inline-block;"><input type="submit" value="Sign In"></span>
</div>
</fieldset>
<div class="clearfix"></div>
}
And Inside my login controller I have a simple ActionResult named Verify with the 2 params.
[RoutePrefix("Login")]
public class LoginController : Controller
{
// GET: Login
public ActionResult Index()
{
return View();
}
[HttpPost]
[Route("Verify")] //Matches GET login/verify
public ActionResult Verify(string username, string password)
{...}
What exactly am I doing wrong here? It's not like this is rocket science.
Edit2:
I've noticed that whenever I change the RouteConfig.cs back to default it works correctly. So, the problem isn't inside the form tags but within the routings.
So I've been trying to add a custom route in order to get this working using this sample: Using Html.BeginForm() with custom routes
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "TrailersOverview",
url: "{TrailersOverview}/{action}/{vendid}",
defaults: new { controller = "TrailersOverview", action = "Index", vendId = UrlParameter.Optional }
);
routes.MapRoute(
"MyCustomRoute", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "login", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
name: "Default",
url: "{*anything}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
);
}
}
When I remove the routings and I simply bring everything back to default, the controller does get hit. Unfortunately I really need those routings for the rest of the app :(
There are several things that seems to be wrong:
Your Controller is missing in the route Config.
Action and Controller names are in wrong order.
RouteConfig:
A default route looks like that:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}/",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Form:
If you want to use Tag Helpers, then you have to change your code from:
<form action="#Url.Action("Login", "Verify")" method="post">
to:
<form asp-controller="Login" asp-action="Verify" method="post">
Have a look here.
#using (Html.BeginForm("Verify", "YourControllerName", FormMethod.Post))
{ your form here // }
please try this if it works !
One more thing add name attribute in your input fields which should be similar to the property name in your model like
#Html.TextBoxFor(m => m.UserName, new { #class = "form-control", id="username", name="USERNAME"})
And this USERNAME should be there in your model like:
Public class yourModel{Public string USERNAME{get;set;}}
And use your Model Object in your Action Method to fetch data.
Your custom route (the second in your RegisterRoutes code above) seems to be incorrect... based on what you stated above, it can/should be this:
routes.MapRoute(
"MyCustomRoute", // Route name
"Login/Verify", // (No parameters needed)
new { controller = "Login", action = "Verify" } // Parameter defaults
);
With this setup, alter the first line of your razor code to be this:
#using (Html.BeginRouteForm("MyCustomRoute", FormMethod.Post }))
{
<fieldset class="clearfix">
...
}
Using Html.BeginRouteForm will automatically use the defaults specified in your custom route; no need to add the defaults in Razor. Using FormMethod.Post as the second parameter will render your form's method as a POST.
Edit:
Let's fix your general Route problem. You're attempting to use Attribute Routing, which is described well here: https://www.dotnettricks.com/learn/mvc/understanding-attribute-routing-in-aspnet-mvc. I'd contend that it isn't necessary here.
First, fix your default Route (last route in your RegisterRoutes code) like so:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
// Change the 'controller' and 'action' parameters here to point to the Main page in your application.
Your default Route is very important, and should be configured as a catch-all for any requests can be simply mapped to a Controller/Action combination. I suspect that you experienced problems because your default Route was altered.
Next, comment out the Route and RoutePrefix attributes in your Login Controller... there's hardly a need for the [Route("Verify")] directive if you're using 'RegisterRoutes' properly.
// [RoutePrefix("Login")]
public class LoginController : Controller
{
// GET: Login
public ActionResult Index()
{
return View();
}
[HttpPost]
// [Route("Verify")] //Matches GET login/verify
public ActionResult Verify(string username, string password)
{...}
}
Now that the default Route is set up properly, the url '/Login' should take you to your Login screen, because the default action is "Index" (it's the default in your default Route above.)
Try adding routes.LowercaseUrls = true; to your route config as you seem to prefer lower-case versions of routes:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.LowercaseUrls = true;
routes.MapRoute(
name: "TrailersOverview",
url: "{TrailersOverview}/{action}/{vendid}",
defaults: new { controller = "TrailersOverview", action = "Index", vendId = UrlParameter.Optional }
);
routes.MapRoute(
"MyCustomRoute", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "login", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
name: "Default",
url: "{*}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
);
}
}
And for the default route, I think you wanted to mention {*} for url to match everything else?
New to the world of Web API and I can't seem to get any custom view to display. I've done the basics, made a method in my controller that seems to be linked corrected where I'm calling it. I'm more familiar with MVC so I'm wondering am I missing something basic here? The view always returns an error can't be accessed for me.
The ActionResult, in the generated HomeController:
[HttpGet]
public ActionResult SpotDetails()
{
ViewBag.Title = "Spot Details";
return View();
}
The link to call it in the menu:
<ul class="nav navbar-nav">
<li>#Html.ActionLink("SHOR //", "Index", "Home", new {area = ""}, null)</li>
<li>#Html.ActionLink("Index", "Index", "Home", new {area = ""}, null)</li>
<li>#Html.ActionLink("Spot Profile", "SpotDetails", "Home", new {area = ""}, null)</li>
<li>#Html.ActionLink("API", "Index", "Help", new {area = ""}, null)</li>
</ul>
I should say the links to the index and the api help pages work perfectly.
This is my RouteConfig in case it's at fault, I haven't touched it at all:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
And finally my WebApiConfig:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.Formatters.Remove(config.Formatters.XmlFormatter);
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling =
Newtonsoft.Json.ReferenceLoopHandling.Ignore;
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
Edit - the error message when the link is clicked:
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: /Home/SpotDetails
Most likely this is an issue with your startup configuration. Routes must be registered in order from most specific to least specific. You have accounted for that within your RouteConfig.RegisterRoutes and WebApiConfig.Register methods. However, you must also call WebApiConfig.Register before RouteConfig.RegisterRoutes or your Default route will take precedence over any of the Web API routes.
WebApiConfig.Register(GlobalConfiguration.Configuration);
RouteConfig.RegisterRoutes(RouteTable.Routes);
So.. i have a MVC webpage. I have defined a Controller
public class NinjaController : Controller
{
// GET: Ninja
public ActionResult Index()
{
return View();
}
}
The my routes are set up like this:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute("Default", "{controller}/{action}/{id}", new
{
controller = "Login",
action = "Login",
id = UrlParameter.Optional
});
}
}
And i have a Folder in the Views folder that is named Ninja and an Index.cshtml file in there that looks like this:
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
Very simple... This is a business application with lots of different settings and configurations... If i do the exact same thing in a new solution it works just fine...
However when i try to access (http://localhost:1235/Ninja) view i get the following error:
{"A public action method 'Login' was not found on controller 'Stimline.Xplorer.Web.Controllers.NinjaController'."}
To me it seems like there should be something confusing the routing function.. but i have no idea where this logic could be placed... anyone have any suggestions?
Interesting fact: If i change the name of the method from Index() to OhYea() and create a corresponding view everything works as expected....
Your routing configuration is saying that pretty much all routes should go to Login which is why your Ninja route doesn't work.
The recommended way of enforcing authentication against a particular route is to use the AuthorizeAttribute. To summarise, keep your default route
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Ninja", action = "Index", id = UrlParameter.Optional }
);
But restrict your NinjaController to authorized users only
[Authorize]
public class NinjaController : Controller
{
...
}
So, I am trying to submit a form on a List Page(http://example.com:3480/List) which is actually a Search implementation. So far I have done this:
index.cshtml
#using(Html.BeginForm("Search","ListController"))
{
<input id=query type=text name=query />
<input id=btnsearch type=submit value=Search />
}
ListController.cs
[HttpPost]
public ActionResult Search(FormCollection collection)
{
Response.Write("We are here");
// Get Post Params Here
string var1 = collection["query"];
Response.Write(var1);
return View();
}
Global.asax
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Details",
"Details/{id}/{orderid}",
new { controller = "Details", action = "Index", id = UrlParameter.Optional, orderid = UrlParameter.Optional }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional} // Parameter defaults
);
}
Upon Clicking it goes to http://example.com:3480/ListController/Search which seems fine.
Now I guess I need to define route in Global.aspx but not sure. What I want is to show result in same View file instead of creating a new one.
At this moment I am unable to get into Search method after POSTing form
Assuming you are currently just using the default route, the reason you are not reaching the action method is that the "Controller" suffix on your route is implicit - it shouldn't be part of your URL.
#using(Html.BeginForm("Search","List"))
Additionally, regarding:
What I want is to show result in same View file instead of creating a new one.
You can easily return a specific view from any controller action by specifying the name of the view in the call to the View method:
return View("Index");
I'm an MVC newbie so this might sound trivial.I have my 2 Views(EnterLogin.aspx,ShowLogin.aspx) in a folder called LoginForm in Views.
Here is my Global.asax.cs below
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "LoginForm", action = "ShowLogin", id = UrlParameter.Optional } // Parameter defaults
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
}
Here is my ShowLogin.aspx design code
<form method="post" action="EnterLogin" runat="server">
Hello, i'm login page
Enter Name <asp:TextBox ID="txtName" runat="server"></asp:TextBox>
<input type="submit" value="PressMe" />
</form>
Here are my controllers
public class LoginFormController : Controller
{
public ActionResult ShowLogin()
{
return View();
}
public ActionResult EnterLogin()
{
return View("EnterLogin");
}
}
On running the application it first loads with url
http://localhost:50224/
and shows the ShowLogin.aspx View
On clicking the button I'm calling EnterLogin controller to show EnterLogin View but it looks in URL
http://localhost:50224/EnterLogin
instead of
http://localhost:50224/LoginForm/EnterLogin
What could be causing this?
The reason you're not landing where you want to is the action portion of your form:
action="EnterLogin"
This should follow the correct route to ensure it hits the LoginFormController. e.g.
action="/LoginForm/EnterLogin"
Remember that the incoming request needs to match a route specified in RegisterRoutes. Because you don't have anything directly matching EnterLogin it will try to use EnterLogin to fill in the {controller} then default to ShowLogin as the action (resulting in a failed request). basically:
EnterLogin ==resolves==> EnterLogin /ShowLogin/
{controller}/{action} /{id}
Alternatively you can make a named route that will redirect to the correct location if you want to short-hand it:
action="LogMeIn"
and then:
routes.MapRoute(
"Login",
"LogMeIn",
new { controller = "LoginForm", action = "EnterLogin" }
);
Now requesting /LogMeIn will execute LoginForm's EnterLogin() action.
The default route defined in Global.asax defines routes which have /controller/action.
Your controller is called LoginForm and your action is called EnterLogin so this is expected behaviour.
If you want to exclude LoginForm from the URL, you need to define a custom route to allow for this.
routes.MapRoute(
"LoginForm_EnterLogin", // Route name
"LoginForm/EnterLogin/{id}", // URL with parameters
new { controller = "LoginForm", action = "ShowLogin", id = UrlParameter.Optional } // Parameter defaults
);
You may do something like this
Global.asax.cs :-
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "LoginForm", action = "ShowLogin", id = UrlParameter.Optional } // Parameter defaults
);
ShowLogin.aspx :-
<form method="post" action="EnterLogin" runat="server">
Hello, i'm login page
Enter Name <input type="text" name="txtName"/>
<input type="submit" value="PressMe" /> </form>
LoginFormController :-
public class LoginFormController : Controller
{
public ActionResult ShowLogin()
{
return View();
}
[HttpPost]
public ActionResult EnterLogin(FormCollection collection)
{
string Yourtxtname=Collection["txtName"]; //You will get input text value
return View();
}
}