ASP MVC onclick for button - c#

Ive just started to play around with ASP MVC and I come from a background of Web Forms.
Ive started a MVC internet application and wanted to know how a button calls an action from a controller. Here I would like to use the log in example that is provided with an MVC Internet application.
AccountController:
Lots of methods
Login View:
#using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Log in Form</legend>
<ol>
<li>
#Html.LabelFor(m => m.UserName)
#Html.TextBoxFor(m => m.UserName)
#Html.ValidationMessageFor(m => m.UserName)
</li>
<li>
#Html.LabelFor(m => m.Password)
#Html.PasswordFor(m => m.Password)
#Html.ValidationMessageFor(m => m.Password)
</li>
<li>
#Html.CheckBoxFor(m => m.RememberMe)
#Html.LabelFor(m => m.RememberMe, new { #class = "checkbox" })
</li>
</ol>
<input type="submit" value="Log in" />
</fieldset>
so when I hit the sumbit button on the view, which method in the AccountController class will be called? and how do you work it out?
Thanks all :)

When you click submit button you send a post request,and in your AccounController this Controller Action should called:
[HttpPost]
public ActionResult Login(Usermodel model)
{
}
I suggest you to watch this tutorial to learn MVC Controllers,Actions and some other stuff.It is a good training.
Edit: In MVC when you type a URL like localhost/Home/Index first it goes Home Controller and looking for an Index action, and it must be [HttpGet] action because your request is a Get request. But you don't need to mark your Action with HttpGet Attribute because it's default behaviour.It works like this way because of your RouteConfig.Your controllers return Views, if you look at your HomeController and AccountController you will see all actions returning a View, and if you Right click your action and click Go To the View you will see your View which belongs to your controller.

I presume you're talking about the default ASP.NET MVC Template, in this case you'll see that in the Login.cshtml view, you have a model defined at the top:
#model MyApp.Models.LoginModel
This will bind your view to this model. When you do a POST it will gather html elements from your form with names corresponding to the model properties.
#using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
...
}
This here creates a html form that will do a post to /Account/Login. However you can specify a different location:
#using (Html.BeginForm("Index", "Home", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post)) {
...
}
On the server side you'll be expecting the same model:
public ActionResult Login(LoginModel model, string returnUrl)
{
// awesomeness ...
}

Ive just started to play around with ASP MVC and I come from a
background of Web Forms
use ajax post on button click as same in aspx with url as action name and controller name, this is the closest you can get with webforms
$.ajax({
url: '#Url.Action("SendMail", "Contact")',
type: 'POST',
data: { listID: selected.toString(), flag: flag },
traditional: true,
success: function (result) {
}
});
or you can use whole form post using default way in MVC
[HttpPost]
public ActionResult SendMail(Mail model)
{
}
coz you have defined
#using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
on your view, which will point to default action through route, However you can change the default action explicitly defining desired action name and controller name using
#using (Html.BeginForm("ActionName", "ControllerName", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post)) {

Related

Attribute routing

How do you hook up a textbox to a method in MVC5 using attribute routing, with areas?
This is view:
#using (Html.BeginForm())
{
#Html.TextBox("searchpara")
#Html.ActionLink("Search", "SearchMethod", "Home", new { area = "Timetables" }, null)
}
Controller:
[RouteArea("Timetables")]
[RoutePrefix("Home")]
public class HomeController : Controller
{
Method:
[Route("SearchMethod/{searchpara=Test}")]
public ActionResult SearchMethod(string searchpara)
{
It doesn't work. The problem may not be routing?
I believe you want a submit button, and not an action link and you may need to update the form to post to a specific action if it is not the current action.
#using (Html.BeginForm("SearchMethod", "Home", new { area = "Timetables" }))
{
#Html.TextBox("searchpara")
<button type="submit">Search</button>
}

Ajax.Actionlink forwarding to Get method while setting httpmethod to post

Controller's get and post method
[HttpGet]
public ActionResult Index()
{
SoSession.Authenticate("pierre", "pierre");
return View();
}
[HttpPost]
public ActionResult Index(CompanySearch model)
{
return RedirectToAction("Companies",new{searchString=model.SearchString});
}
in view
#using (Html.BeginForm("Index", "Company"))
{
<div class="input-block-level">
#Html.TextBoxFor(m => m.SearchString)
#Ajax.ActionLink(
"Submit",
"Index",
new{},
new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "partialDiv" })
</div>
}
<div id="partialDiv"></div>
Problem
Whenever user clicks submit link i get forwarded to get method and not post method. How do i forward the call to post method of my controller?
Make sure you have the unobutrusive ajax library file (and it's dependencies (jQuery)) loaded to your view properly. If you do not have this file loaded to your page, Clicking on the link produced by Ajax.ActionLink helper method will do a GET request instead of the asynchronous POST you were expecting.
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
It sounds like you are trying to use an ajax form:
#using Ajax.BeginForm("Submit", "Company", FormMethod.Post, new AjaxOptions { UpdateTargetId = "partialDiv", InsertionMode = InsertionMode.Replace}) {
#Html.TextBoxFor(m => m.SearchString)
}
If you include the ajax js libraries that should work.
You can also use JQuery for the partial load although the controller would return a partial. I do agree with mayabelle that Ajax.BeginForm() is another route to take.
[HttpGet]
public ActionResult Companies(string searchString)
{
return this.PartialView("MyView", MyObject)
}
inside of the cshtml javascript:
var searchString = $("#SearchString").val();
$("#partialDiv").load('#Url.Content("~/Home/Companies/")' + searchString, function(){ DoSomething(); });

Html.BeginForm rendering with "/" action

I have the following route defined
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Account", action = "Login", id = UrlParameter.Optional }
);
I am then trying to use Html.BeginForm as below
<% using (Html.BeginForm("Login", "Account", System.Web.Mvc.FormMethod.Post, new { #class = "login-form" }))
{ %>
But this renders me a form like below
<form class="login-form" action="/" method="post">
</form>
However if i change my defaults on me route to be something different like
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Login", id = UrlParameter.Optional }
);
My form then renders correctly, for info i am using Html.BeginForm() in a partial view that is returned from the login method on my account controller.
public class AccountController : Controller
{
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(LoginModel model)
{
if (ModelState.IsValid)
{
//TODO: Login user
}
return View(model);
}
}
The behavior that you are noticing is expected and is also correct. When generating links MVC goes through the list of routes in the route collection(top-down) and sees which routes can match based on the route data that you are providing in Html.BeginForm. For example, you can imagine a request coming in like POST / and in this case your Account controller's Login action would be called because of the presence of defaults.
Actually it is expected behaviour. Actually routing system is pretty clever and it knows the request which is coming that is for the default values.(In your case default controller is Account and default action is Login and in your begin form you are using the same controller and action).
So routing system will replace it
by '/'.
You can verify it by just adding one another controller let say Admin and the same View Login. And now just replace the controller by new controller like
<% using (Html.BeginForm("Login", "Admin", System.Web.Mvc.FormMethod.Post,
new { #class = "login-form" }))
Now you will have link like
<form class="login-form" action="/Admin" method="post"></form>
There will be no action, because routing system will find the action is default action.
Thanks

How to get url parameter value of current route in view in ASP .NET MVC

For example I am on page http://localhost:1338/category/category1?view=list&min-price=0&max-price=100
And in my view I want to render some form
#using(Html.BeginForm("Action", "Controller", new RouteValueDictionary { { /*this is poblem place*/ } }, FormMethod.Get))
{
<!--Render some controls-->
<input type="submit" value="OK" />
}
What I want is to get view parameter value from current page link to use it for constructing form get request. I tried #using(Html.BeginForm("Action", "Controller", new RouteValueDictionary { { "view", ViewContext.RouteData.Values["view"] } }, FormMethod.Get)) but it doesn't help.
I've found the solution in this thread
#(ViewContext.RouteData.Values["view"])
You should still have access to the Request object from within the view:
#using(Html.BeginForm(
"Action",
"Controller",
new RouteValueDictionary {
{ "view", Request.QueryString["view"] } }, FormMethod.Get))
You can't access Request object directly in ASP .NET Core. Here is a way to do it.
#ViewContext.HttpContext.Request.Query["view"]
From an MVC perspective, you would want to pass the value from the controller into the page e.g.
public ActionResult ViewCategory(int categoryId, string view)
{
ViewBag.ViewType = view;
return View();
}
Then in your view you an access #ViewBag.ViewType, you will need to cast it to a string though as it will by default be object (ViewBag is a dynamic object).

How do you pass a model from Editor for model into a controller? (using asp.net)

#model mymodelsnamespace
#using (Html.BeginForm("MyMethodName", "MyContollerName", FormMethod.Post))
{
#Html.EditorFor(m => Model, "Submit", new { multiple = true })
<input type="submit" value="Submit" />
}
I know the code I am going write will be close to whats above
How do I passed the updated model into MyMethodName is i can continue to manipulate it in my controller?
Please provide the signature for MyMethodName and the cshtml to give the model to the method in the controller.
If you add this code to your controller, it should work.
[HttpPost]
public ActionResult MyMethodName (YourModel model)
{
... some code here.
}
You may find the Model-View-ViewModel pattern interesting.

Categories

Resources