Value is not getting pass from view to action method - asp.net-mvc-3

i am new in mvc. i have design a form and when i am click the submit button then right action method is calling but form field's value are not getting pass.
here is my view code
<div id="mydiv">
#using (Html.BeginForm("Save", "Game", FormMethod.Post, new { #Id = "Form1" }))
{
<table border="0">
<tr>
<td>Name :</td>
<td><input name="name" type="text" /></td>
</tr>
<tr>
<td>Salary :</td>
<td><input name="salary" type="text" /></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Save" /> </td>
</tr>
</table>
}
</div>
here is my action method
public ActionResult Save(string str1, string str2)
{
return View("Message");
}
when save is getting called the str1 & str2 is being null please help me to pass value and also discuss various trick to pass value from view to action method. thanks

Change you controller
public ActionResult Save(string name, string salary)
{
return View("Message");
}
As you have to use variable name which you have defined in input
<input name="name" type="text" />
<input name="salary" type="text" />
If you want to return partial view.
return PartialView("Message", <<OptionalPartialViewModel>>);

You should start by learning about conventions in ASP.NET MVC. You should use models for communicating between controllers and views.
Create a model type first:
public class SalaryModel
{
public string Name { get; set; }
public string Salary { get; set; }
}
Create your form by using HTML helpers and strongly typing your view:
#model SalaryModel
<div id="mydiv">
#using (Html.BeginForm("Save", "Game", FormMethod.Post, new { #Id = "Form1" }))
{
<table border="0">
<tr>
<td>Name :</td>
<td>#Html.TextBoxFor(item => item.Name)</td>
</tr>
<tr>
<td>Salary :</td>
<td><input name="salary" type="text" /></td>
</tr>
<tr>
<td colspan="2">#Html.TextBoxFor(item => item.Salary)</td>
</tr>
</table>
}
</div>
Then you can get the form values inside the model:
[HttpPost]
public ActionResult Save(SalaryModel model)
{
return View("Message");
}
There's a great tutorial on ASP.NET MVC website that can help you with the basics.

MVC Bind form inputs to Action by their names. You should change your method params as the same of the form. Also, you are missing the HttpPost attribute:
[HttpPost]
public ActionResult Save(string name, string salary)
{
/*Do Stuff here*/
return View("Message");
}

Related

ASP.NET Core 3.1 MVC : sending selected checkboxes to controller

I have following list view with checkboxes:
#model IEnumerable<PaketServisAracTakip.Models.Item>
#{
ViewData["Title"] = "Yükleme Yap";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2 class="text-center text-success">#ViewBag.name İsimli Araca Yükleme Yap</h2>
<form asp-controller="Vehicle"
asp-action="LoadItem" method="post">
<br />
<input type="submit" name="submit" value="Oluştur" class="btn btn-primary" />
</form>
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th class="text-center">
Yüklensin mi?
</th>
<th class="text-center">
#Html.DisplayNameFor(model => model.Name)
</th>
<th class="text-center">
#Html.DisplayNameFor(model => model.Price)
</th>
<th class="text-center">
#Html.DisplayNameFor(model => model.Description)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
<div class="form-check">
<label class="form-check-label" for="#item.Id" asp-validation-for="#item.Id"></label>
<input class="form-check-input" name="ids" type="checkbox" value="#item.Id" id="#item.Id">
</div>
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
₺#Html.DisplayFor(modelItem => item.Price)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
</tr>
}
</tbody>
</table>
And my item model with database integrated:
[Table("Items")]
public class Item
{
[Key]
public int Id { get; set; }
[Display(Name = "İsim")]
[Required(ErrorMessage ="{0} alanı boş bırakılamaz.")]
[MaxLength(50, ErrorMessage ="İsim 50 karakteri geçemez.")]
public String Name { get; set; }
[Display(Name = "Fiyat")]
[Required(ErrorMessage = "{0} alanı boş bırakılamaz.")]
[Range(0, Double.MaxValue, ErrorMessage = "Minimum 0 girmelisin.")]
public int Price { get; set; }
[Display(Name = "Açıklama")]
public String Description { get; set; }
}
view
So when button is clicked i want to get checked items in my controller. I tried this but its empty:
[HttpPost]
public ActionResult LoadItem(IEnumerable<Item> model)
{
return RedirectToAction("Index");
}
I also tried int array and FormCollection but didn't work. I think I need some tag helpers but don't know which.
when button is clicked i want to get checked items in my controller. I
tried this but its empty
Please check the code in the View Page, since the table doesn't in the <form> element, when you click the Submit button, the submitted form doesn't contain the related data.
Besides, to submit the model data to the controller using model binding, we should use the #for statement to loop through the entities and use hidden fields to store the related data. Please refer the following sample and change your code:
Model:
[Table("Items")]
public class Item
{
[Key]
public int Id { get; set; }
[Display(Name = "İsim")]
[Required(ErrorMessage = "{0} alanı boş bırakılamaz.")]
[MaxLength(50, ErrorMessage = "İsim 50 karakteri geçemez.")]
public String Name { get; set; }
[Display(Name = "Fiyat")]
[Required(ErrorMessage = "{0} alanı boş bırakılamaz.")]
[Range(0, Double.MaxValue, ErrorMessage = "Minimum 0 girmelisin.")]
public int Price { get; set; }
[Display(Name = "Açıklama")]
public String Description { get; set; }
public Boolean IsChecked { get; set; } //add a property to store whether the item is check or not.
}
View page:
#model List<netcore3_1sample.Models.Item>
#{
ViewData["Title"] = "ItemIndex";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2 class="text-center text-success">#ViewBag.name İsimli Araca Yükleme Yap</h2>
<form asp-controller="Home"
asp-action="LoadItem" method="post">
<br />
<input type="submit" name="submit" value="Oluştur" class="btn btn-primary" />
<br />
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th class="text-center">
Yüklensin mi?
</th>
<th class="text-center">
Name
</th>
<th class="text-center">
Price
</th>
<th class="text-center">
Description
</th>
</tr>
</thead>
<tbody>
#for( var i = 0; i < Model.Count;i++)
{
<tr>
<td>
<div class="form-check">
<label class="form-check-label" for="#Model[i].Id" asp-validation-for="#Model[i].Id"></label>
<input class="form-check-input" name="ids" type="checkbox" value="#Model[i].Id" id="#Model[i].Id">
#*<input type="checkbox" asp-for="#Model[i].IsChecked" />*#
<input type="hidden" asp-for="#Model[i].Id" />
</div>
</td>
<td>
#Html.DisplayFor(modelItem => Model[i].Name)
<input type="hidden" asp-for="#Model[i].Name" />
</td>
<td>
₺#Html.DisplayFor(modelItem => Model[i].Price)
<input type="hidden" asp-for="#Model[i].Price" />
</td>
<td>
#Html.DisplayFor(modelItem => Model[i].Description)
<input type="hidden" asp-for="#Model[i].Description" />
</td>
</tr>
}
</tbody>
</table>
</form>
Code in the controller:
[HttpPost]
public ActionResult LoadItem(List<Item> model, int[] ids)
{
return RedirectToAction("ItemIndex");
}
According to your code, you are using a html checkbox element to store the selected Item ID, so here we need to add an array to get the selected ids.
Besides, you could add a IsChecked property in the Item model, then change the following code:
<input class="form-check-input" name="ids" type="checkbox" value="#Model[i].Id" id="#Model[i].Id">
to
<input type="checkbox" asp-for="#Model[i].IsChecked" />
By using this method, in the controller, you could filter the selected item based on the IsChecked property.
The result like this:

How to send table data from HTML form submit via ajax call to Spring MVC controller

Say i have a HTML table in a format similar to this
<form> <table id="a">
<thead>
<th>Name</th>
<th>Series</th>
<th>Value</th>
</thead>
<tbody id="b">
<tr><td>Enhancer</td><td>Enhancement</td><td>50</td></tr>
<tr><td>Plans</td><td>Plan</td><td>50</td></tr>
</tbody>
</table>
<input type="submit" value="Send" action="SomeControllerAction" /></form>
which has two rows under the headings "Name","Series" and "Value" .
I need to send this data via a form submit to a Spring Controller with Ajax where i can get or set the values for each row iteratively in a Model.
I am not sure how to achieve this . That is how to send the data in a table to a spring controller method and get the values .
Help with code segments!
Thanks
Although the previous answer is correct, I would suggest to introduce a class that contains three fields : name, series and value.
This class should have a meaningful name.
Here I named it MyObject because I don't know what you app is about.
MyObject :
public class MyObject {
private String name, series;
private Integer value;
// Getters and setters
}
Controller (the return type might be different)
#PostMapping("/series")
#ResponseBody
public List<MyObject> postSeries(#RequestBody List<MyObject> myObjects) {
myObjects.forEach(System.out::println);
// Handle myObjects
return myObjects;
}
JSP
<table id="tableMyObjects">
<thead id="a">
<tr>
<th>Name</th>
<th>Series</th>
<th>Value</th>
</tr>
</thead>
<tbody id="b">
<tr>
<td><input type="text" name="name" /></td>
<td><input type="text" name="series" /></td>
<td><input type="text" name="value" /></td>
</tr>
<tr>
<td><input type="text" name="name" /></td>
<td><input type="text" name="series" /></td>
<td><input type="text" name="value" /></td>
</tr>
</tbody>
</table>
<button id="postButton">Post myObjects</button>
jQuery
$('#postButton').click(function() {
var myObjects = [];
$('#b tr').each(function(index, item) {
var $item = $(item);
myObjects.push({
name: $item.find("td input[name='name']").val(),
series: $item.find("td input[name='series']").val(),
value: $item.find("td input[name='value']").val(),
});
});
$.ajax({
url: '/series',
method: 'POST',
contentType : 'application/json; charset=utf-8',
data: JSON.stringify(myObjects)
})
.done(function(myObjects) {
// handle success
})
.fail(function() {
// handle fail
});
});
Using javascript/jquery you can do that easily.
Generate a input type hidden text field while iterating the table content like below with the same name.
<tbody id="b">
<tr>
<td>
<input type="hidden" name="Name" value="Enhancer" />
Enhancer
</td>
<td>
<input type="hidden" name="Series" value="Enhancement" />
Enhancement
</td>
<td>
<input type="hidden" name="Value" value="50" />
50
</td>
</tr>
</tbody>
and then get all the hidden fields values by name like below.
$("[name='Name']").val();
$("[name='Series']").val();
$("[name='Value']").val();
and then in controller accept those parameters as an array like below.
#RequestMapping(method = RequestMethod.POST, produces = "text/html")
public String create(#RequestParam(value = "Name") String[] Name,
#RequestParam(value = "Series") String[] Series,
#RequestParam(value = "Value") String[] Value,
BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest){
//code goes here
}
NOTE : You have to write javascript code to set the hidden field values for multiple rows something like this Call javascript function with if JSTL

How are Spring MVC Controllers being bound to JSP pages?

Hi I am new to spring and I am trying to develop a simple portlet that accepts users first and last name and saves it to db using hibernate.
Basically I cannot figure out how the jsps and controllers communicate; I am missing some chunk here.
This is my first controller that needs to be called (where do I mention so?)
package codes.controller;
import javax.portlet.RenderResponse;
import codes.base.User;
import codes.service.UserService;
#Controller(value="SimpleUserController")
#RequestMapping(value = "VIEW")
public class SimpleUserController {
// -- auto-wiring of service dependency
#Autowired
#Qualifier("userService")
private UserService userService;
// --maps the incoming portlet request to this method
#RenderMapping
public String showUsers(RenderResponse response) {
return "home";
}
#ExceptionHandler({ Exception.class })
public String handleException() {
return "errorPage";
}
// -- #ModelAttribute here works as the referenceData method
#ModelAttribute(value="user")
public User getCommandObject() {
return new User();
}
}
Initially I am displaying a home.jsp that will display the form with two input boxes and a submit button.
<%#include file="include.jsp" %>
<portlet:actionURL var="addUserActionUrl">
<portlet:param name="myaction" value="addUser" />
</portlet:actionURL>
<form:form name="home" commandName="user" method="post"
action="${addUserActionUrl}">
<table>
<tr>
<td>First Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="firstname" /></td>
</tr>
<tr>
<td>Last Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="lastname" /></td>
</tr>
<table align="right">
<tr>
<td> </td>
<td><input type="submit" value="SUBMIT" /></td>
</tr>
</table>
</table>
</form:form>
This JSP should call the action method in the AddUserController.java:
package codes.controller;
import javax.portlet.ActionResponse;
import javax.portlet.RenderResponse;
import codes.base.User;
import codes.service.UserService;
#Controller(value = "AddUserController")
#RequestMapping(value = "VIEW")
public class AddUserController {
#Autowired
#Qualifier("userService")
private UserService userService;
#RenderMapping(params = "myaction=addUser")
public String showRegisterPage(Model model) {
model.addAttribute("user", new User());
model.addAttribute("users", getUsers());
return "addUser";
}
public List<User> getUsers() {
return userService.getAllUsers();
}
#ActionMapping(params = "myaction=addUser")
public void addBook(#ModelAttribute(value = "user") User user,
BindingResult bindingResult, ActionResponse response,
SessionStatus sessionStatus) {
if (!bindingResult.hasErrors()) {
userService.addUser(user);
response.setRenderParameter("myaction", "users");
sessionStatus.setComplete();
} else {
response.setRenderParameter("myaction", "addUser");
}
}
}
This time this firstname+last name should be saved in the db AND the screen should refresh to show a new form that will have a dropdown with the current users' names in the database and another first name and last name form fields. If you select a username from the dropdown the form fields are populated and you can edit these values and click on UPdate button to save the values in DB. Otherwise you can add a new user to the database using submit button.
addUser.jsp:
<%#include file="include.jsp" %>
<portlet:actionURL var="addUserActionUrl">
<portlet:param name="myaction" value="addUser" />
</portlet:actionURL>
<portlet:renderURL var="homeUrl">
<portlet:param name="myaction" value="Users" />
</portlet:renderURL>
<script type="text/javascript" src="js/userRelated.js"></script>
<form:form name="addUser" commandName="user" method="post"
action="${addUserActionUrl}">
<form:select path="model">
<form:option value="NONE" label="--- Select ---" id="userList" onchange="showHide()"/>
<form:options items="${users}" />
</form:select>
<table>
<tr>
<td>First Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="firstname" /></td>
</tr>
<tr>
<td>Last Name:<font style="color: #C11B17;">*</font></td>
<td><form:input path="lastname" /></td>
</tr>
<table align="right">
<tr>
<td> </td>
<td><input type="submit" id="submit" value="SUBMIT" />SUBMIT</td>
</tr>
<tr>
<td> </td>
<td><input type="submit" id="update" value="SUBMIT" />UPDATE</td>
</tr>
</table>
</table>
</form:form>
I am hiding and unhiding the SUBMIT/UPDATE button using onchange of dropdown. How do I call different functions in the addUsercontroller depending on the button available?
by updating the action attribute of form element with javascript

How to do a bulk persist on a partial view?

I have written a partial view that displays a list of rows, where some fields in the row are editable using a textbox, checkbox, or whatever.
I would like the parent view to have a "submit" button that posts the whole collection of updated rows so that I can do a group update rather than posting once for every updated row.
Here's what I have:
public class GroupModel {
public string SomeGenericProperty { get; set; }
public IEnumerable<ItemModel> Items { get; set; }
}
public class ItemModel {
public long ID { get; set; }
public string Field1 { get; set; }
public string Field2 { get; set; }
}
Then I have a view "GroupDetails":
#model MyNamespace.GroupModel
...
#using (Html.BeginForm("SaveItems", "Home")) {
<fieldset>
...
#Html.Partial("ItemList", Model.Items)
...
<input type="submit" value="Approve" />
</fieldset>
}
And a partial view "ItemList":
#model IEnumerable<MyNamespace.ItemModel>
<table>
<tr>
<th>
Field 1
</th>
<th>
Field 2
</th>
<th>
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.TextBoxFor(modelItem => item.Field1)
</td>
<td>
#Html.TextBoxFor(modelItem => item.Field2)
</td>
<td>
#Html.HiddenFor(i => item.ID)
</td>
</tr>
}
</table>
But when I post, the information from partial view is not being posted; the GroupModel object's Items property is null.
What's the right way to do this?
I would recommend you to always use editor templates. The reason your code doesn't work is because you used a partial and this partial doesn't inherit the parent template context which means that helpers that are used inside it will generate wrong names for the input fields.
For example if you look at the source code of your page you will see this:
<td>
<input type="text" name="[0].Field1" id="[0]_Field1" />
</td>
instead of the correct name which is:
<td>
<input type="text" name="Items[0].Field1" id="Items[0]_Field1" />
</td>
I would recommend you reading the following blog post to better understand the wire format that the default model binder expects.
So start by fixing your main view first and replace the partial with an editor template:
#model MyNamespace.GroupModel
#using (Html.BeginForm("SaveItems", "Home"))
{
<fieldset>
...
<table>
<thead>
<tr>
<th> Field 1 </th>
<th> Field 2 </th>
<th></th>
</tr>
</thead>
<tbody>
#Html.EditorFor(x => x.Items)
</tbody>
</table>
...
<input type="submit" value="Approve" />
</fieldset>
}
and then define a custom editor template that will be rendered for each element of the model (~/Views/Shared/EditorTemplates/ItemModel.cshtml - this works by convention, it should be either inside ~/Views/Shared/EditorTemplates if you want it to be reused among controllers or inside ~/Views/Home/EditorTemplates if you want this template to be available only for the Home controller - and the name of the template must be the type of the collection - in your case it is ItemModel.cshtml):
#model MyNamespace.ItemModel
<tr>
<td>
#Html.TextBoxFor(x => x.Field1)
</td>
<td>
#Html.TextBoxFor(x => x.Field2)
</td>
<td>
#Html.HiddenFor(x => x.ID)
</td>
</tr>
Now everything will bind fine and dandy in your controller action:
[HttpPost]
public ActionResult SaveItems(GroupModel model)
{
...
}

How to authorise user from the forum's main page?

I'm trying to implement a simple blog, which contains topics
models/Topic.cs
public class Topic
{
public int ID {get; set;}
[StringLength(50)]
[RequiredAttribute(ErrorMessage = "*")]
public string Title {get; set;}
[StringLength(1024)]
[RequiredAttribute(ErrorMessage = "*")]
public string Body { get; set; }
public int CommentsCount { get; set; }
public DateTime TimeLastUpdated { get; set; }
public int AuthorID { get; set; }
public virtual List<Comment> commentsList { get; set; }
}
Main Page looks like a list of topics.
Controllers/HomeController.cs
public class HomeController : Controller
private ContentStorage db = new ContentStorage();
public ViewResult Index()
{
// Topics = DbSet<Topic> Topics { get; set; }
return View(db.Topics.ToList());
}
[HttpPost]
public void LogIn(string login, string password)
{
int i;
i = 10;
}
}
Main page's view is very simple.
Views/Home/Index
#model IEnumerable<MvcSimpleBlog.Models.Topic>
...
<table width="95%" height="86" border="0">
<tr>
<td width="45%" valign = "bottom" >Login:</td>
<td width="45%" valign = "bottom" >Password:</td>
<td width="10%"></td>
</tr>
<tr>
<td width="45%"><p> <input type="text" name="login" /> </p></td>
<td width="45%"><p><input type="password" name="password" /></p></td>
<td width="10%" align = "left">
#using (Html.BeginForm("LogIn", "Home"))
{
<input type = "submit" value = "Enter" />
}
</td>
</tr>
<tr>
<td width="45%" valign = "top" >#Html.ActionLink("Register", "Register", "Account")</td>
</tr>
</table>
How could i pass the values from edit boxes in the View to the HomeController method? The method "LogIn" was supposed to receive data from the view, call the "Account" controller, passing user's login and password to it. An "Account" controller shoud validate this user and redirect browser to the main page with topics.
But i can't access login and password edit boxes in the view... and i really don't know what should i do, and is my model correct
Those input fields should be inside your Html.BeginForm if you want their values to be posted to the server when the form is submitted. Currently you only have a single submit button inside your form. So:
#using (Html.BeginForm("LogIn", "Home"))
{
<table width="95%" height="86" border="0">
<tr>
<td width="45%" valign="bottom">Login:</td>
<td width="45%" valign="bottom">Password:</td>
<td width="10%"></td>
</tr>
<tr>
<td width="45%">
<p>
<input type="text" name="login" />
</p>
</td>
<td width="45%">
<p>
<input type="password" name="password" />
</p>
</td>
<td width="10%" align="left">
<input type="submit" value="Enter" />
</td>
</tr>
<tr>
<td width="45%" valign="top">
#Html.ActionLink("Register", "Register", "Account")
</td>
</tr>
</table>
}
Now your LogIn controller action could receive the 2 values as action parameters like so:
[HttpPost]
public ActionResult LogIn(string login, string password)
{
... perform authentication
}

Resources