I am using
#Html.CheckBoxFor(model => model.AllowOrder, new { id = "allowOrder"})
Now I want to pass its value (whether checked or unchecked) to the controller. I am using html.BeginForm for posting back the data to controller. Every time I am getting its value as null in action method. Action method has below sample code.
public ActionResult index(bool isChecked)
{
// code here
}
isChecked property is passed in as null always. Any help please. TIA.
If you don't want to return to controller whole data model, but only one value then see code below:
public IActionResult IndexTest()
{
var model = new ViewModel() { AllowOrder = true };
return View(model);
}
[HttpPost]
public IActionResult IndexTest(bool isChecked)
{
// your code here...
return View("IndexTest", new ViewModel() { AllowOrder = isChecked} );
}
Using the onclick() to trace the checkbox state:
#model ViewModel
<script>
function onStateChange() {
var item = document.getElementById('allowOrder');
var chk = false;
if (item.checked) {
chk = true;
}
document.getElementById('isChecked').value = chk;
};
</script>
#using (Html.BeginForm())
{
#Html.Hidden("isChecked", Model.AllowOrder)
#Html.CheckBoxFor(r => Model.AllowOrder, new { id = "allowOrder", #onclick = "onStateChange()" })
<input id="Button" type="submit" value="Save" />
}
View:
#model <specifyModelhere>
#using(Html.BeginForm("index","<YourControllerNameHere>",FormMethod.Post))
{
#Html.CheckBoxFor(r => Model.AllowOrder)
<input id="Button" type="submit" value="Save" />
}
Controller:
public ActionResult index(<YourModelNameHere> model)
{
var ischecked = model.AllowOrder;
// code here
}
This way when you submit the form, the entire model will be posted back and you can receive it in the controller method
Related
i'm making a webbapplication with ASP.NET MVC and im trying to edit my list of objects. If i for example add a product to the site and then click on edit for that product to change the prize i just get a new object with the new prize instead of changing the prize to the product.
So the problem is that instead of updating the products it just adds a new one.
this is how my controller for the products looks like:
using auktioner_MarcusR91.Data;
using auktioner_MarcusR91.Models;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace auktioner_MarcusR91.Controllers
{
public class InventoryController : Controller
{
private readonly AppDbContext _db;
public InventoryController(AppDbContext db)
{
_db = db;
}
public IActionResult Index()
{
IEnumerable<Inventory> objInventoryList = _db.Inventories;
return View(objInventoryList);
}
//GET
public IActionResult Create()
{
return View();
}
//Post
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Inventory inventory)
{
_db.Inventories.Add(inventory);
_db.SaveChanges();
return RedirectToAction("index");
}
//GET
public IActionResult Edit(int? id)
{
if (id == 0 || id == 5)
{
return NotFound();
}
var inventoryFromDb = _db.Inventories.Find(id);
if (inventoryFromDb == null)
{
return NotFound();
}
return View(inventoryFromDb);
}
//Post
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Edit(Inventory inventory)
{
if (ModelState.IsValid)
{
_db.Inventories.Update(inventory);
_db.SaveChanges();
return RedirectToAction("index");
}
return View(inventory);
}
}
}
I think there is something wrong in my controller.
However here is also my view for when i edit a product:
#model Inventory
<form method = "post" asp-action = "Edit">
<div class = "border p-3 mt-4">
<div class = "row pb-2">
<h2 class = "text-primary">Edit Inventory</h2>
<hr />
</div>
<div class = "mb-3">
<label asp-for ="inventoryName"></label>
<input asp-for = "inventoryName" />
<label asp-for ="finalPrize"></label>
<input asp-for = "finalPrize" />
<label asp-for ="inventoryDesc"></label>
<input asp-for = "inventoryDesc" />
<p>1 för "Transport</p>
<p>2 för "Smycken"</p>
<p>3 för "Hushåll"</p>
<p>4 för "Dekoration"</p>
<select asp-for = "categoryId">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
</select>
</div>
<button type = "submit" class = "btn btn-primary" width = "100px">Update</button>
<a asp-controller = "Inventory" asp-action = "index" class = "btn btn-secondary" style = "width: 100px">Back to products</a>
</div>
</form>
You have to add a primary key inventoryId as a hidden input, without this key , you inventory instance looks like a new one for EF.
And since you are using [ValidateAntiForgeryToken] in the action, add this to view with another form syntax
#using (Html.BeginForm("Edit", "Inventory", FormMethod.Post))
{
#Html.AntiForgeryToken()
<input type="hidden" asp-for="inventoryId" value="#Model.inventoryId" />
....
<button type = "submit" class = "btn btn-primary" width = "100px">Update</button>
<a asp-controller = "Inventory" asp-action = "index" class = "btn btn-secondary" style = "width: 100px">Back to products</a>
</div>
}
and IMHO your update code could be like this
if (ModelState.IsValid)
{
var inventoryFromDb = _db.Inventories.Find(inventory.inventoryId);
if (inventoryFromDb == null)
{
return NotFound();
}
_db.Entry(inventoryFromDb).CurrentValues.SetValues(inventory);
var result= _db.SaveChanges();
}
You have to send your record id to the controller by clicking update button of the record . something like this :
<a class="btn btn-warning btn-sm btn-margin" asp-controller="ContextController" asp-action="UpdateAction" ***asp-route-id="#item.Id***">Update</a>
which #item is the object of the model sent to the view .
And the action would be :
[HttpGet]
public IActionResult UpdateAction(int id)
{
Model record = _Context.GetById(id);
return View("UpdateFormPageOrModal",record);
}
And after updating the form and clicking the submit button of the view data will send to action :
[HttpPost]
public IActionResult UpdateAction(Model record)
{
var result = _Context.UpdateBy(record);
ViewData["Result"] = result.Message;
if (result.IsSucceeded)
{
_UnitOfWork.Save();
return RedirectToAction("TheGridView");
}
return View("UpdateView",record);
}
where UpdateBy() method should be like this :
public void UpdateBy(T entity)//entity is an object of the DbSet<Model>
{
var state = _Context.Entry(entity).State;
if (state == EntityState.Detached)
{
_Context.Attach(entity);
}
_Context.Entry(entity).State = EntityState.Modified;
}
#model IEnumerable<Evidencija.Models.Vozilo>
#{
ViewBag.Title = "PokreniIzvjestaj";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>PokreniIzvjestaj</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Vozilo</legend>
<p>
#Html.DropDownList("Vozila", Model.Select(p => new SelectListItem { Text = p.VoziloID.ToString(), Value = p.VoziloID.ToString() }), "Izaberi vozilo")
</p>
<input type="submit" value="Dodaj stavku" />
</fieldset>
}
I want to send id of table vozilo to controler with dropdownlist.
Controler accepts vozilo as a parameter but it is ollways zero.
How can I solve this without using viewmodel.
[HttpPost]
public ActionResult PokreniIzvjestaj(Vozilo v)
{
ReportClass rpt = new ReportClass();
rpt.FileName = Server.MapPath("~/Reports/Vozilo.rpt");
rpt.Load();
//ReportMethods.SetDBLogonForReport(rpt);
//ReportMethods.SetDBLogonForSubreports(rpt);
// rpt.VerifyDatabase();
rpt.SetParameterValue("#VoziloId",v.VoziloID);
Stream stream = null;
stream = rpt.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
return File(stream, "application/pdf", "Vozilo.pdf");
//PortableDocFormat--pdf format
//application/pdf -- vezan za pdf format, ako je drugi tip mjenja se u zavisnosti od izabranog
//naziv.pdf -- naziv dokumenta i izabrana ekstenzija
}
[HttpGet]
public ActionResult PokreniIzvjestaj()
{
var vozila = db.Voziloes.ToList();
return View(vozila);
}
There are two method from controler.
You currently binding your drop down to a property named Vozilo. A <select> post back single value (in your case the VoziloID or the selected option. Your POST method then tries to bind a complex object Vozilo to an int (assuming VoziloID is typeofint) which of course fails and the model isnull`. You could solve this changing the method to
[HttpPost]
public ActionResult PokreniIzvjestaj(int Vozilo)
The parameter Vozilo will now contain the value of the selected VoziloID.
However it not clear why you want to "solve this without using viewmodel" when using a view model is the correct approach
View model
public class VoziloVM
{
[Display(Name = "Vozilo")]
[Required(ErrorMessage = "Please select a Vozilo")]
public int? SelectedVozilo { get; set; }
public SelectList VoziloList { get; set; }
}
Controller
public ActionResult PokreniIzvjestaj()
{
var viziloList = db.Voziloes.Select(v => v.VoziloID);
VoziloVM model = new VoziloVM();
model.VoziloList = new SelectList(viziloList)
model.SelectedVozilo = // set a value here if you want a specific option selected
return View(model);
}
[HttpPost]
public ActionResult PokreniIzvjestaj(VoziloVM model)
{
// model.SelectedVozilo contains the value of the selected option
....
}
View
#model YourAssembly.VoziloVM>
....
#Html.LabelFor(m => m.SelectedVozilo)
#Html.DropDownListFor(m => m.SelectedVozilo, Model.VoziloList, "-Please select-")
#Html.ValidationMessageFor(m => m.SelectedVozilo)
....
How to get the textbox value from view to controller in mvc4?If I using httppost method in controller the page cannot found error was came.
View
#model MVC_2.Models.FormModel
#{
ViewBag.Title = "DisplayForm";
}
#using (Html.BeginForm("DisplayForm", "FormController", FormMethod.Post))
{
<form>
<div>
#Html.LabelFor(model => model.Empname)
#Html.TextBoxFor(model => model.Empname)
#* #Html.Hidden("Emplname", Model.Empname)*#
#Html.LabelFor(model => model.EmpId)
#Html.TextBoxFor(model => model.EmpId)
#* #Html.Hidden("Emplid", Model.EmpId)*#
#Html.LabelFor(model => model.EmpDepartment)
#Html.TextBoxFor(model => model.EmpDepartment)
#* #Html.Hidden("Empldepart", Model.EmpDepartment)*#
<input type="button" id="submitId" value="submit" />
</div>
</form>
}
model
public class FormModel
{
public string _EmpName;
public string _EmpId;
public string _EmpDepartment;
public string Empname
{
get {return _EmpName; }
set { _EmpName = value; }
}
public string EmpId
{
get { return _EmpId;}
set {_EmpId =value;}
}
public string EmpDepartment
{
get { return _EmpDepartment; }
set { _EmpDepartment = value; }
}
}
controller
public ActionResult DisplayForm()
{
FormModel frmmdl = new FormModel();
frmmdl.Empname=**How to get the textbox value here from view on submitbutton click???**
}
First you need to change your button type to "submit". so your form values will be submitted to your Action method.
from:
<input type="button" id="submitId" value="submit" />
to:
<input type="submit" id="submitId" value="submit" />
Second you need to add your model as parameter in your Action method.
[HttpPost]
public ActionResult DisplayForm(FormModel model)
{
var strname=model.Empname;
return View();
}
Third, If your Controller name is "FormController". you need to change the parameter of your Html.Beginform in your view to this:
#using (Html.BeginForm("DisplayForm", "Form", FormMethod.Post))
{
//your fields
}
P.S.
If your view is the same name as your Action method which is "DisplayForm" you don't need to add any parameter in the Html.BeginForm. just to make it simple. like so:
#using (Html.BeginForm())
{
//your fields
}
Have an ActionResult for the form post:
[HttpPost]
public ActionResult DisplayForm(FormModel formModel)
{
//do stuff with the formModel
frmmdl.Empname = formModel.Empname;
}
Look into Model Binding. Default model binding will take the data embedded in your posted form values and create an object from them.
Let's implement simple ASP.NET MVC subscription form with email textbox.
Model
The data from the form is mapped to this model
public class SubscribeModel
{
[Required]
public string Email { get; set; }
}
View
View name should match controller method name.
#model App.Models.SubscribeModel
#using (Html.BeginForm("Subscribe", "Home", FormMethod.Post))
{
#Html.TextBoxFor(model => model.Email)
#Html.ValidationMessageFor(model => model.Email)
<button type="submit">Subscribe</button>
}
Controller
Controller is responsible for request processing and returning proper response view.
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Subscribe(SubscribeModel model)
{
if (ModelState.IsValid)
{
//TODO: SubscribeUser(model.Email);
}
return View("Index", model);
}
}
Here is my project structure. Please notice, "Home" views folder matches HomeController name.
You model will be posted as a object on the action and you can get it in action on post like this:
[HttpPost]
public ActionResult DisplayForm(FormModel model)
{
// do whatever needed
string emp = model.EmpName;
}
it you are posting data always put HttpPost attribute on the action.
Your view also has mistakes, make it like this:
#using (Html.BeginForm("DisplayForm", "Form", FormMethod.Post))
{
<div>
#Html.LabelFor(model => model.Empname)
#Html.TextBoxFor(model => model.Empname)
#* #Html.Hidden("Emplname", Model.Empname)*#
#Html.LabelFor(model => model.EmpId)
#Html.TextBoxFor(model => model.EmpId)
#* #Html.Hidden("Emplid", Model.EmpId)*#
#Html.LabelFor(model => model.EmpDepartment)
#Html.TextBoxFor(model => model.EmpDepartment)
#* #Html.Hidden("Empldepart", Model.EmpDepartment)*#
<input type="button" id="submitId" value="submit" />
</div>
}
There are two ways you can do this.
The first uses TryUpdateModel:
public ActionResult DisplayForm()
{
FormModel frmmdl = new FormModel();
TryUpdateModel (frmmdl);
// Your model should now be populated
}
The other, simpler, version is simply to have the model as a parameter on the [HttpPost] version of the action:
[HttpPost]
public ActionResult DisplayForm(FormModel frmmdl)
{
// Your model should now be populated
}
Change your controller like below.
[HttpPost]
public ActionResult DisplayForm(FormModel model)
{
var Empname = model.Empname;
}
You need to have both Get and Post Methods:
[HttpGet]
public ActionResult DisplayForm()
{
FormModel model=new FormModel();
return View(model);
}
[HttpPost]
public ActionResult DisplayForm(FormModel model)
{
var employeeName=model.Empname;
return View();
}
[HttpPost]
public ActionResult DisplayForm(FormModel model)
{
var value1 = model.EmpName;
}
Model values from hidden field? I recommend the strongly typed approach shown below:
public ActionResult DisplayForm(string Emplname, string Emplid, string Empldepart)
[HttpPost]
public ActionResult DisplayForm(FormModel model)
{
FormModel frmmdl = new FormModel();
frmmdl.Empname=**How to get the textbox value here from view on submitbutton //click???**
}
model.Empname will have the value
I am trying to display a Partial View inside a master (Index) View:
Steps:
User selects a Dropdown item from the Index View.
This displays a Partial View that has a search Form.
User fills the search Form and then clicks the Submit button.
If the search Form is valid, a new page (Results View) is displayed.
Else, the search Form Partial View should be re displayed with errors INSIDE the master View
I'm having a problem with number 4 because when the search Form submits, it only displays the partial View in a new window. I want to display the whole page : Index View + Partial View with errors.
Suggestions? This is what I have:
Image
Controller
public class AppController : Controller
{
public ActionResult Index()
{
return View(new AppModel());
}
public ActionResult Form(string type)
{
if (type == "IOS")
return PartialView("_IOSApp", new AppModel());
else
return PartialView("_AndroidApp", new AppModel());
}
public ActionResult Search(AppModel appModel)
{
if (ModelState.IsValid)
{
return View("Result");
}
else // This is where I need help
{
if (appModel.Platform == "IOS")
return PartialView("_IOSApp", appModel);
else
return PartialView("_AndroidApp", appModel);
}
}
}
Model
public class AppModel
{
public string Platform { get; set; }
[Required]
public string IOSAppName { get; set; }
[Required]
public string AndroidAppName { get; set; }
public List<SelectListItem> Options { get; set; }
public AppModel()
{
Initialize();
}
public void Initialize()
{
Options = new List<SelectListItem>();
Options.Add(new SelectListItem { Text = "IOS", Value = "I" });
Options.Add(new SelectListItem { Text = "Android", Value = "A"});
}
}
Index.cshtml
#{ ViewBag.Title = "App Selection"; }
<h2>App Selection</h2>
#Html.Label("Select Type:")
#Html.DropDownListFor(x => x.Platform, Model.Options)
<div id="AppForm"></div> // This is where the Partial View goes
_IOSApp.cshtml
#using (Html.BeginForm("Search", "App"))
{
#Html.Label("App Name:")
#Html.TextBoxFor(x => x.IOSAppName)
<input id="btnIOS" type="submit" value="Search IOS App" />
}
AppSearch.js
$(document).ready(function () {
$("#Platform").change(function () {
value = $("#Platform :selected").text();
$.ajax({
url: "/App/Form",
data: { "type": value },
success: function (data) {
$("#AppForm").html(data);
}
})
});
});
You need to call the search method by ajax too.
Change the index.html and then
1- if Form is valid replace the whole html or the mainContainer( The div that i have added to view).
2- else just replace the partial view.
#{ ViewBag.Title = "App Selection"; }
<div id="mainContainer">
<h2>App Selection</h2>
#Html.Label("Select Type:")
#Html.DropDownListFor(x => x.Platform, Model.Options)
<div id="AppForm"></div> // This is where the Partial View goes
</div>
Remove the form tag from your partial view just call an ajax call method for searching.
May be easiest way to handle this problem is using MVC unobtrusive ajax.
I would say use inline Ajax to submit this form.
#using (Html.BeginForm("Search", "App"))
{
#Html.Label("App Name:")
#Html.TextBoxFor(x => x.IOSAppName)
<input id="btnIOS" type="submit" value="Search IOS App" />
}
change upper given code into following code
#using (
Ajax.BeginForm(
"Form", "App",
new AjaxOptions()
{
UpdateTargetId = "App",
HttpMethod = "Post"
}
)
)
{
<div class="editor-label">
#Html.Label("App Name:")
</div>
<div class="editor-field">
#Html.TextBoxFor(x => x.IOSAppName)
</div>
<input id="btnIOS" type="submit" value="Search IOS App" />
}
//in controller change the parameter of the given method from string type to model object which will be posted by ajax form.
public ActionResult Form(AppModel appModel)
{
if (appModel.type == "IOS")
return PartialView("_IOSApp", new AppModel());
else
return PartialView("_AndroidApp", new AppModel());
}
Hi I have got a drop downlist that I am binding that one in controller I have got one button in view with that I am doing some validations that's working fine,
when I submit the button for validation check i am not able to get the view with error message. Instead of this I am getting error like this " The view 'PostValues' or its master was not found or no view engine supports the searched locations".
would any one help on why I am not able to get the view
here the view is strongly Typed view
and this is my code in controller.
public class CrossFieldsTxtboxesController : Controller
{
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index()
{
var model = NewMethod();
return View(model);
}
private static CrossFieldValidation NewMethod()
{
var model = new CrossFieldValidation
{
SelectedValue = "Amount",
Items = new[]
{
new SelectListItem { Value = "Amount", Text = "Amount" },
new SelectListItem { Value = "Pound", Text = "Pound" },
new SelectListItem { Value = "Percent", Text = "Percent" },
}
};
return model;
}
[HttpPost]
public ActionResult PostValues(CrossFieldValidation model1)
{
model1 = NewMethod();
if (!ModelState.IsValid)
{
return View(model1);
}
else
{
return RedirectToAction("Index");
}
}
}
and this is my view
#model MvcSampleApplication.Models.CrossFieldValidation
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using (Html.BeginForm("PostValues", "CrossFieldsTxtboxes"))
{
#Html.ValidationSummary(true)
<div class ="editor-field">
#Html.TextBoxFor(m => m.TxtCrossField)
#Html.ValidationMessageFor(m=>m.TxtCrossField)
</div>
#Html.DropDownListFor(m=> m.SelectedValue , Model.Items)
<input id="PostValues" type="Submit" value="PostValues" />
}
would any one pls help on this...
This line
return View(model1);
looks for the view named exactly like the action in which it was called. Calling this line from PostValues action assumes there is a view PostValues.cshtml (which apparently does not exist). If you still want to use view Index - you should specify this explicitly:
if (!ModelState.IsValid)
{
return View("Index", model1);
}
As Andrei said. Alternatively, you can give your PostValues method an additional tag:
[HttpPost, ActionName("Index")]
public ActionResult PostValues(CrossFieldValidation model1)
{
if (!ModelState.IsValid)
{
return View(model1);
}
}