How to link HTML5 form action to Controller ActionResult method in ASP.NET MVC 4 - asp.net-mvc

I have a basic form for which I want to handle buttons inside the form by calling the ActionResult method in the View's associated Controller class. Here is the following HTML5 code for the form:
<h2>Welcome</h2>
<div>
<h3>Login</h3>
<form method="post" action= <!-- what goes here --> >
Username: <input type="text" name="username" /> <br />
Password: <input type="text" name="password" /> <br />
<input type="submit" value="Login">
<input type="submit" value="Create Account"/>
</form>
</div>
<!-- more code ... -->
The corresponding Controller code is the following:
[HttpPost]
public ActionResult MyAction(string input, FormCollection collection)
{
switch (input)
{
case "Login":
// do some stuff...
break;
case "Create Account"
// do some other stuff...
break;
}
return View();
}

you make the use of the HTML Helper and have
#using(Html.BeginForm())
{
Username: <input type="text" name="username" /> <br />
Password: <input type="text" name="password" /> <br />
<input type="submit" value="Login">
<input type="submit" value="Create Account"/>
}
or use the Url helper
<form method="post" action="#Url.Action("MyAction", "MyController")" >
Html.BeginForm has several (13) overrides where you can specify more information, for example, a normal use when uploading files is using:
#using(Html.BeginForm("myaction", "mycontroller", FormMethod.Post, new {enctype = "multipart/form-data"}))
{
< ... >
}
If you don't specify any arguments, the Html.BeginForm() will create a POST form that points to your current controller and current action. As an example, let's say you have a controller called Posts and an action called Delete
public ActionResult Delete(int id)
{
var model = db.GetPostById(id);
return View(model);
}
[HttpPost]
public ActionResult Delete(int id)
{
var model = db.GetPostById(id);
if(model != null)
db.DeletePost(id);
return RedirectToView("Index");
}
and your html page would be something like:
<h2>Are you sure you want to delete?</h2>
<p>The Post named <strong>#Model.Title</strong> will be deleted.</p>
#using(Html.BeginForm())
{
<input type="submit" class="btn btn-danger" value="Delete Post"/>
<text>or</text>
#Url.ActionLink("go to list", "Index")
}

Here I'm basically wrapping a button in a link. The advantage is that you can post to different action methods in the same form.
<a href="Controller/ActionMethod">
<input type="button" value="Click Me" />
</a>
Adding parameters:
<a href="Controller/ActionMethod?userName=ted">
<input type="button" value="Click Me" />
</a>
Adding parameters from a non-enumerated Model:
<a href="Controller/ActionMethod?userName=#Model.UserName">
<input type="button" value="Click Me" />
</a>
You can do the same for an enumerated Model too. You would just have to reference a single entity first. Happy Coding!

Related

How to get Input control value in controller's Index method asp.net core

I am working on captcha authentication. I want to get user entered captcha value in controller's Index method. Below is my cshtml file code
#{
ViewData["Title"] = "Home Page";
}
<div class="container">
<label for="captcha"><b>Enter chaptcha - </b></label>
<label id="lblshowCaptcha"><b>#ViewData["captcha"]</b></label>
<input id="txtCapValue" type="text" placeholder="Enter captcha" name="cap" required>
<br/>
<button class="button" type="submit">Login</button>
<br />
</div>
When user entering captcha value in txtCapValue and click submit button I need that value in controller. Here is my controller
public IActionResult Index()
{
randnumber = RandomString(6);
ViewData["captcha"] = randnumber;
return View();
}
how can I get txtCapValue input control value when user click on submit button ?
One of the easy ways using the Form Tag Helper:
<form asp-controller="Controller_Name" asp-action="Captcha" method="post">
<div class="container">
<label for="captcha"><b>Enter chaptcha - </b></label>
<label id="lblshowCaptcha"><b>#ViewData["captcha"]</b></label>
<input id="txtCapValue" type="text" placeholder="Enter captcha" name="cap" required>
<br />
<button class="button" type="submit">Login</button>
<br />
</div>
</form>
And on the server side:
[HttpPost]
public IActionResult Captcha(string cap)
{
... using the `cap`
return View("Index");
}
I want to get user entered captcha value in controller's Index
method.
There are two options, you can try:
Option1: use Form Tag Helper
Index method:
public IActionResult Index(string cap)
{
ViewData["captcha"] = 6;//do your staff
return View();
}
Index view:
<form method="get" asp-action="Index">
<div class="container">
<label for="captcha"><b>Enter chaptcha - </b></label>
<label id="lblshowCaptcha"><b>#ViewData["captcha"]</b></label>
<input id="txtCapValue" type="text" placeholder="Enter captcha" name="cap" required>
<br />
<button class="button" type="submit">Login</button>
<br />
</div>
</form>
Option 2: use ajax
Index method:
public IActionResult Index(string cap)
{
ViewData["captcha"] = 6;
return View();
}
Index view:
<div class="container">
<label for="captcha"><b>Enter chaptcha - </b></label>
<label id="lblshowCaptcha"><b>#ViewData["captcha"]</b></label>
<input id="txtCapValue" type="text" placeholder="Enter captcha" name="cap" required>
<br />
<button id="buttonDemo1" class="button" type="submit">Login</button>
<br />
</div>
#section scripts{
<script type="text/javascript">
$(document).ready(function () {
$('#buttonDemo1').click(function () {
var cap = $("#txtCapValue");
$.ajax({
type: 'GET',
url: '/Home/Index',
data: cap
});
});
});
</script>
}
result:

How redirect action with all params

I have action in controller Statistic
public ViewResult Index(string userName, GridSortOptions gridSortOptions, int? page, DateTime? dateTimeFrom, DateTime? dateTimeTo)
{
..
}
I create partial view _FromToDateViewPage.cshtml
<script language="javascript">
$(function () {
$("#datepickerFrom").datepicker();
$("#datepickerTo").datepicker();
});
</script>
<div class="date_box">
<p><span>Date From: <input type="text" id="datepickerFrom"></span><span>Date To: <input type="text" id="datepickerTo"></span></p>
#Html.RouteLink("Filter", new { Controller = ViewContext.Controller.ValueProvider.GetValue("controller").RawValue, Action = ViewContext.Controller.ValueProvider.GetValue("action").RawValue, dateTimeFrom = DateTime.Now })
</div><!-- Date (From To) Picker Box -->
I need a filter button that sends the current effect that all options were. And + dateTimeFrom and dateTimeTo
In your view you have to use a submit button and not a link.
<form>
<input type="hidden" name="page" value="#ViewBag.page">
<input type="hidden" name="username" value="#ViewBag.username">
<!-- deserialize the gridSortOptions -->
<input type="hidden" name="gridSortOptions_field" value="#ViewBag.gridSortOptions_field">
<input type="hidden" name="gridSortOptions_field" value="#ViewBag.gridSortOptions_direction">
<!-- add the value attribute and set it's value to datepickerFrom stored in viewBag -->
Date From: <input type="text" id="datepickerFrom" name="datepickerFrom" value="#ViewBag.datepickerFrom">
<!-- add the value attribute and set it's value to datepickerTostored in viewBag -->
Date To: <input type="text" id="datepickerTo" name="datepickerTo" value="#ViewBag.datepickerTo">
<input type="submit">
</form>

Hide/Disable submit button from controller

How can I hide a webform button from controller action? or Do I do it in webform itself?
There is a condition to hide/disable the button:
if (StudentType != "Senior")
{
Hide Button
}
Display Button
View:
<form method="post" action="/Student/Dispatch/">
<label for="id">Student Number: </label>
<input type="text" name="id" value="" /> <br /><br />
<input type="submit" value="Get Student(xls)" name="xls" /> &nbsp
<input type="submit" value="Get Student(pdf)" name="pdf" />
</form>
Controller:
[HttpPost]
public ActionResult Dispatch(string pdf, string id) {
if (!string.IsNullOrEmpty(pdf)) {
// GetPdf submit button was clicked
return StudentPdf(id);
}
// GetXls submit button was clicked
return StudentExcel(id);
}
You can use ViewData dictionary .
Controller:
if (StudentType != "Senior")
{
ViewData["isHideButton"] =true;
}
View:
<form method="post" action="/Student/Dispatch/">
<label for="id">Student Number: </label>
<input type="text" name="id" value="" /> <br /><br />
<% bool hideButton= false;
bool.TryParse(ViewData["isHideButton"],hideButton)%>
<%if(!hideButton)
{%>
<input type="submit" value="Get Student(xls)" name="xls" />
<%}%>
&nbsp <input type="submit" value="Get Student(pdf)" name="pdf" />
</form>

Get Model back in Post

Is there any way to get information from my model during a result flagged HttpPost if I cannot pass it as a parameter?
[AcceptVerbs(HttpVerbs.Post)]
public FileUploadJsonResult Upload(HttpPostedFileBase file, IwantMyModelToo! )
I can't really get the actual view model to go through the method, though. Any thoughts?
Here is the primary view. (FoldersController)
<hr class="space" />
<div>
<% Html.RenderAction<Controllers.ImagesController>(i => i.Create(Model)); %>
</div>
<hr class="space" />
Here is the partial view (ImagesController, where the Create method resides)
// bunch of fun jQuery for jQuery Form Uploading.
</script>
<div class="span-24 last">
<fieldset>
<legend>Upload Image</legend>
<form id="ajaxUploadForm" action="<%= Url.Action("Upload", "Images")%>" method="post" enctype="multipart/form-data" >
<div>
<label for="file">Select Image</label><br />
<input type="file" name="file" />
</div>
<input id="ajaxUploadButton" type="submit" value="Upload" />
</form>
</fieldset>
</div>
In your code sample there are no properties connected to any model... Here I have added one (Foo) in a hidden form field, and created a class called MyModel.
View
<div class="span-24 last">
<fieldset>
<legend>Upload Image</legend>
<form id="ajaxUploadForm" action="<%= Url.Action("Upload", "Images")%>" method="post" enctype="multipart/form-data" >
<div>
<%= Html.Hidden("Foo", "bar") %>
</div>
<div>
<label for="file">Select Image</label><br />
<input type="file" name="file" />
</div>
<input id="ajaxUploadButton" type="submit" value="Upload" />
</form>
</fieldset>
</div>
Model
public class MyModel
{
public string Foo {get;set;}
}
Controller
public FileUploadJsonResult Upload(HttpPostedFileBase file, MyModel model)
{
//model.Foo should be accessible here
}

Multiple forms in ASP.NET MVC

Context
Let`s say i have:
In layout Site.Master:
<div class="leftColumn">
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
</div>
<div class="rightColumn">
<% Html.RenderPartial("_Login"); %>
<asp:ContentPlaceHolder ID="SideContent" runat="server" />
</div>
Login partialView looks like:
<form action="/myApp/Account/Login" method="post">
<input name="name" />Name<br />
<input name="password" type="password" />Password<br />
<button>Login</button>
</form>
Is it possible to update only login widget form, not the entire content page?
If you are referring to a http post, only a post initiated (it can also be initiated by javascript) by a submit button from within the form will be posted to the server.
If your forms are nested then this won't work. The outer form will always post to the server.
In the sample HTML below, clicking on the submit button on the first form will not send the values from the second form to the server. Likewise, clicking the second submit button won't post the values from the first form.
<html>
...
<body>
<div>
<form action="/Login/Login" method="post">
<input type="text" name="username" value="" />
<input type="text" name="passowrd" value="" />
<input type="submit" name="login" value="Login" />
</form>
<form action="/Login/AdminLogin" method="post">
<input type="text" name="username" value="" />
<input type="text" name="passowrd" value="" />
<input type="submit" name="login" value="Login Admin" />
</form>
</div>
</body>
</html>
If you only wish to update/change one of the form section, then no this can not be done without using javascript and performing a javascript post(aka Ajax).
If you build a controller method that accepts a FormCollection and your view has two forms defined, the formcollection returned will either be populated with values from form A or form B. You can inspect the formCollection and branch your logic based on the value therein. If you want the be very explicit you could have the same hidden variable occur in both forms with a value that would help your make your choice.
That's one approach. there are a few ways to deal with this I'm sure.
If you have two simple forms, you can use this aproach:
You create two different partial views.
#model CustomerInfoModel
#using (Ajax.BeginForm("CustomerInfo", "Customer", new AjaxOptions { HttpMethod = "Post", OnBegin = "InfoLoading", OnComplete = "InfoCompleted" }, new { id = "info", #class = "form-horizontal" }))
{
<input type="text" class="form-control" name="Name" id="Name" value="#Model.Name" />
<input type="email" class="form-control" name="Email" id="Email" value="#Model.Email" />
<button type="submit" id="save-info" class="btn-medium red">Save</button>
}
and
#model CustomerPasswordChangeModel
#using (Ajax.BeginForm("CustomerPasswordChange", "Customer", new AjaxOptions { HttpMethod = "Post", OnBegin = "InfoLoading", OnComplete = "InfoCompleted" }, new { id = "change", #class = "form-horizontal" }))
{
<input type="password" class="form-control" name="OldPassword" id="OldPassword" value="" />
<input type="password" class="form-control" name="NewPassword" id="NewPassword" value="" />
<button type="submit" id="save-change" class="btn-medium red" autocomplete="off">Save</button>
}
In your parent view,
#Html.Partial("CustomerInfo", Model.CustomerInfo)
and
#Html.Partial("CustomerPasswordChange", Model.CustomerPasswordChange)
In Controller:
[HttpPost]
public ActionResult CustomerInfo([Bind(Include = "Name,Email")] CustomerInfoModel model)
{
if (ModelState.IsValid)
return new Json(new { success=true, message="Updated.", errors=null);
// do you logic
return new Json(new { success=false, message="", errors=getHtmlContent(ModelState.Values.SelectMany(v => v.Errors).ToList(), "ModelError"));
}
[HttpPost]
public ActionResult CustomerPasswordChange([Bind(Include = "OldPassword,NewPassword")] CustomerPasswordChangeModel model)
{
if (ModelState.IsValid)
return new Json(new { success=true, message="Updated.", errors=null);
// do you logic
return new Json(new { success=false, message="", errors=getHtmlContent(ModelState.Values.SelectMany(v => v.Errors).ToList(), "ModelError"));
}
This will do what you want to do.
Note: getHtmlContent method is just generating an error message to be displayed on page. Nothing so special. I may share it if required.
Your question is not very clear.
But as far as I could understand, the answer is most likely yes. You can update anything you want depending on the user input.
if(pass != true)
{
ViewData["Message'] = "Hey your login failed!"; Return View("Login")
}
On ViewPage
<form action="/tralala/Account/Login" method="post">
<input name="name" />Name<br />
<input name="password" type="password" />Password<br />
<button>Login</button>
<div style="color: red"><%=ViewData["Message"] %><div>
</form>

Resources