View data not passing to controller. Please note I am using Entity Framework.
Trying to set the values of the Jobcard so that I can save them, but the fields are not binding to the model. Please any help would be appreciated in helping me solve this issue.
View Cshtml
#model Amax.Models.Jobcard
#using (Html.BeginForm("SaveJobcard", "Home", FormMethod.Post))
{
#Html.EditorFor(model => model.Email)
}
<input class="btn btn-sm btn-outline-success type="submit" id="submit" value="Create Jobcard" onclick="location.href='#Url.Action("SaveJobcard", "Home" , FormMethod.Post)'" />
HomeController
[System.Web.Http.HttpPost]
public ActionResult SaveJobcard(Jobcard Jobcard)
{
if (ModelState.IsValid)
{
try
{
}
catch (Exception ex)
{
}
}
return View();
}
DBModel
namespace Amax.Models
{
using System;
using System.Collections.Generic;
public partial class Jobcard
{
public long JCId { get; set; }
public Nullable<long> ClientId { get; set; }
public Nullable<long> ContactId { get; set; }
public string ContactNo { get; set; }
public string Email { get; set; }
public string VatNo { get; set; }
public Nullable<bool> SLA { get; set; }
public string Address { get; set; }
public Nullable<System.DateTime> TofOrder { get; set; }
public Nullable<System.DateTime> TofCompletion { get; set; }
public Nullable<long> ClientSigId { get; set; }
public string CSignature { get; set; }
public Nullable<System.DateTime> ClientSigDate { get; set; }
public Nullable<long> USigId { get; set; }
public string USignature { get; set; }
public string USigDate { get; set; }
public Nullable<int> StatusId { get; set; }
public List<JobCardItem> Item { get; set; }
}
//public JobCardItem()
//{
// Item = new List<JobCardItem>();
//}
}
View Model
namespace Amax.Models
{
public class ViewModel
{
public Jobcard Jobcard { get; set; }
public Client Client { get; set; }
public Contact Contact { get; set; }
public JobCardItem JobCardItem { get; set; }
public Status Status { get; set; }
public User Users { get; set; }
}
}
Jobcard Object empty
Fields Populated on form
Form Submit Network tab details
Adding in the full view html code
#using (Html.BeginForm("SaveJobcard", "Home", FormMethod.Post))
{
<div class="col-md-12 col-sm-12" id="JobCard">
<div class="row">
<div class="col-md-6 col-sm-6">
<div class="row">
<div class="col-md-6 col-sm-6">
<label class="label" style="color:black;">Company Name :</label>
</div>
<div class="col-md-6 col-sm-6">
<select class="form-control" id="ClientId" value="ClientId">
#{
<option value="0">
Please Select
</option>
var Clients = ((Amax.Controllers.HomeController)this.ViewContext.Controller).GetClients();
foreach (var client in Clients)
{
<option onclick="#Url.Action("GetContacts", "Home", new RouteValueDictionary(new { id = #client.ClientId }));" value="#client.ClientId">
#client.ClientName
</option>
}
}
</select>
</div>
</div>
<br />
<div class="row">
<div class="col-md-6 col-sm-6">
<label class="label" style="color:black;">Contact No :</label>
</div>
<div class="col-md-6 col-sm-6">
<input type="text" class="form-control" id="ContactNo" name="ContactNo" />
</div>
</div>
<br />
<div class="row">
<div class="col-md-6 col-sm-6">
<label class="label" style="color:black;">Vat No :</label>
</div>
<div class="col-md-6 col-sm-6">
<input type="text" class="form-control" id="VatNo" name="VatNo" />
</div>
</div>
</div>
<div class="col-md-6 col-sm-6">
<div class="row">
<div class="col-md-6 col-sm-6">
<label class="label" style="color:black;">Contact Person :</label>
</div>
<div class="col-md-6 col-sm-6">
<select class="form-control" id="ContactId" name="ContactId">
<option value="0">
Please Select
</option>
</select>
</div>
</div>
<br />
<div class="row">
<div class="col-md-6 col-sm-6">
<label class="label" style="color:black;">Email</label>
</div>
<div class="col-md-6 col-sm-6">
#Html.EditorFor(model => model.Email)
</div>
</div>
<br />
<div class="row">
<div class="col-md-6 col-sm-6">
<label class="label" style="color:black;">SLA :</label>
</div>
<div class="col-md-3 col-sm-3">
<input type="checkbox" class="form-control" />
</div>
<div class="col-md-3 col-sm-3">
<input type="checkbox" class="form-control" />
</div>
</div>
</div>
</div>
<br />
<div class="row">
<div class="col-md-12 col-sm-12">
<div class="row">
<div class="col-md-3 col-sm-3">
<label class="label" style="color:black;">Address :</label>
</div>
<div class="col-md-9 col-sm-9">
<input type="email" class="form-control" id="Address" name="Address" />
</div>
</div>
</div>
</div>
<br />
<div class="row">
<div class="col-md-12 col-sm-12">
<div class="row">
<div class="col-md-6 col-sm-6">
<div class="row">
<div class="col-md-6 col-sm-6"> <label class="label" style="color:black;">Time & Date of Order :</label></div>
<div class="col-md-6 col-sm-6"><input type="date" /> </div>
</div>
</div>
<div class="col-md-6">
<div class="row">
<div class="col-md-6 col-sm-6"> <label class="label" style="color:black;">Time & Date of Completion :</label></div>
<div class="col-md-6 col-sm-6"><input type="date" /></div>
</div>
</div>
</div>
</div>
</div>
<br />
<div class="row">
<div class="col-md-6 col-sm-6">
<div class="row">
<div class="col-md-6 col-sm-6">
<label class="label" style="color:black;">Assigned Person :</label>
</div>
<div class="col-md-6 col-sm-6">
<select class="form-control" id="assigned" name="assigned">
#{
<option value="0">
Please Select
</option>
var Users = ((Amax.Controllers.HomeController)this.ViewContext.Controller).GetUsers();
foreach (var user in Users)
{
<option value="#user.UserId">
#user.UserName #user.Surname
</option>
}
}
</select>
</div>
</div>
</div>
<div class="col-md-6 col-sm-6">
<div class="row">
<div class="col-md-6 col-sm-6">
<label class="label" style="color:black;">Status :</label>
</div>
<div class="col-md-6 col-sm-6">
<select class="form-control" id="StatusId" name="StatusId">
#{
<option value="0">
Please Select
</option>
var Status = ((Amax.Controllers.HomeController)this.ViewContext.Controller).GetStatus();
foreach (var status in Status)
{
<option value="#status.Id">
#status.Status1
</option>
}
}
</select>
</div>
</div>
</div>
</div>
<input class="btn btn-sm btn-outline-success type="submit" id="submit" value="Create Jobcard" onclick="location.href='#Url.Action("SaveJobcard", "Home" , FormMethod.Post)'" />
<br />
<br />
<br />
<div class="row">
<div class="col-md-12 col-sm-12">
<div class="row">
<div class="col-md-6 col-sm-6">
<div class="row">
<div class="col-md-4"> <label class="label" style="color:black;">#</label></div>
<div class="col-md-8"> <label class="label" style="color:black;">Description</label></div>
</div>
</div>
<div class="col-md-6 col-sm-6">
<div class="row">
<div class="col-md-6"> <label class="label" style="color:black;">Unit Price</label></div>
<div class="col-md-6"> <label class="label" style="color:black;">Total</label></div>
</div>
</div>
</div>
<div class="row" id="JobItems">
#Html.EditorFor(model => model.Item)
</div>
<div class="col-md-2 col-sm-2"> <button class="btn btn-sm btn-success" id="btnAdd"> + </button> <button class="btn btn-sm btn-danger" id="remove_1"> - </button></div>
<br />
<div class="row">
<div class="col-md-6 col-sm-6">
<div class="row">
<div class="col-md-4">
</div>
<div class="col-md-8"></div>
</div>
</div>
<div class="col-md-6 col-sm-6">
<div class="row">
<div class="col-md-6 col-sm-6">Total</div>
<div class="col-md-6 col-sm-6"><label id="Jc_total">R 0.00</label></div>
</div>
</div>
</div>
<br />
<div class="row">
<div class="col-md-12 col-sm-12">
Terms:<br />
1. All equipment remains the property of AMAX until fully paid and client acknowledges that AMAX reserves the right to remove the equipment in the absence of payment.<br />
Client acknowledges that the equipment belongs to AMAX until fully paid and that the client shall not, under any circumstances, alienate, tarnish, destroy or erode the equipment.<br />
Client shall also ensure reasonable use of the equipment and shall ensure that the equipment is not exposed to negative elements which could alienate, tarnish, destroy or erode the goods.<br />
2. Customer agrees that AMAX may remove equipment if not paid within 7 working days of job completion.<br />
3. Customer will allow AMAX access to installation site to remove equipment that is unpaid.<br />
4. All Equipment carries a 1 year manufacturer’s guarantee.<br />
5. The Customer Agrees that the job has been done to his or her satisfaction
</div>
</div>
<br />
<div class="row">
<div class="col-md-12 col-sm-12">
<div class="row">
<dic class="col-md-12 col-sm-12">
Banking Details: Bank: Acc Name: Acc No: Branch Code: Type:
FNB Amax Electronics 623402 97028 251045 Cheque
Proof of payment: Mail accounts#amaxelectronics.co.za Fax: 012 543 2394
Ref: JN Number
</dic>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 col-sm-12 pull-right">
#using (Html.BeginForm("PDF", "Home", FormMethod.Post))
{
<input type="hidden" name="Styles" id="Styles" />
<input type="hidden" name="ExportData" id="ExportData" />
<input type="submit" id="btnSubmit" value="Generate PDF" />
}
#*<button class="btn btn-sm btn-outline-primary" onclick="#Url.Action("PDF", "Home")">Generate PDF</button>*#
</div>
</div>
}
```
Try binding the form values to the parameter in your controller
public ActionResult SaveJobcard([FromForm]Jobcard jobcard)
the solution to the problem was that one has to add form Html tags to wrap inside the
html you want to submit
Wrong
#using (Html.BeginForm("SaveJobcard", "Home", FormMethod.Post))
{
<div class="col-md-12 col-sm-12" id="JobCard">
<div class="row">
<div class="col-md-6 col-sm-6">
<div class="row">
<div class="col-md-6 col-sm-6">
<label class="label" style="color:black;">Company Name :</label>
</div>
<div class="col-md-6 col-sm-6">
<select class="form-control" id="ClientId" value="ClientId">
#{
<option value="0">
Please Select
</option>
var Clients = ((Amax.Controllers.HomeController)this.ViewContext.Controller).GetClients();
foreach (var client in Clients)
{
<option onclick="#Url.Action("GetContacts", "Home", new RouteValueDictionary(new { id = #client.ClientId }));" value="#client.ClientId">
#client.ClientName
</option>
}
}
</select>
</div>
</div>
</div>
</div>
</div>
}
Works Perfect
#using (Html.BeginForm("SaveJobcard", "Home", FormMethod.Post))
{
<form>
<div class="col-md-12 col-sm-12" id="JobCard">
<div class="row">
<div class="col-md-6 col-sm-6">
<div class="row">
<div class="col-md-6 col-sm-6">
<label class="label" style="color:black;">Company Name:</label>
</div>
<div class="col-md-6 col-sm-6">
<select class="form-control" id="ClientId" value="ClientId">
#{
<option value="0">
Please Select
</option>
var Clients = ((Amax.Controllers.HomeController)this.ViewContext.Controller).GetClients();
foreach (var client in Clients)
{
<option onclick="#Url.Action("GetContacts", "Home", new RouteValueDictionary(new { id = #client.ClientId }));" value="#client.ClientId">
#client.ClientName
</option>
}
}
</select>
</div>
</div>
</div>
</div>
</div>
</form>
}
Related
I have a page that is supposed to submit data for a patient evaluation. The page to submit the evaluation comes up fine. It is based on a ViewModel. Here is the ViewModel:
public class SPEPatientEvalVM
{
public int Id { get; set; }
public int ApptId { get; set; }
public int ActivityID { get; set; }
public int VendorID { get; set; }
public int PatientID { get; set; }
[Required(ErrorMessage ="A selection is required.")]
public int OverallRating { get; set; }
[Required(ErrorMessage = "A selection is required.")]
public int AppearProfessComp { get; set; }
[Required(ErrorMessage = "A selection is required.")]
public int EffGatheredInfo { get; set; }
[Required(ErrorMessage = "A selection is required.")]
public int ListenActively { get; set; }
[Required(ErrorMessage = "A selection is required.")]
public int EstabPersRapport { get; set; }
[Required(ErrorMessage = "A selection is required.")]
public int AppropExploreMyFeelings { get; set; }
[Required(ErrorMessage = "A selection is required.")]
public int AddressedMyFeelings { get; set; }
[Required(ErrorMessage = "A selection is required.")]
public int MetMyNeeds { get; set; }
public string PatientComments { get; set; } = String.Empty;
public DateTime DateSubmitted { get; set; }
}
This is mapped and reverse mapped to the model using IMapper.
Anyway this is my controller code:
[HttpGet("[controller]/[action]/{IDAppt}/{ActivityID}/{VendorID}/{PatientID}")]
public async Task<IActionResult> AddSPEPatientEval(int IDAppt, int ActivityID, int VendorID, int PatientID)
{
var patientChoice = GetPatientChoiceList();
patientChoice[0].Selected = true;
ViewBag.PatientChoice = patientChoice;
var evalParams = await _speRepo.GetOpenPatientEval(IDAppt);
ViewBag.Patient = evalParams.SPEPatient;
var speEval = new SPEPatientEvalVM
{
ApptId = IDAppt,
ActivityID = ActivityID,
VendorID = VendorID,
PatientID = PatientID
};
return View(speEval);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddSPEPatientEval(SPEPatientEvalVM model)
{
var patientChoice = GetPatientChoiceList();
patientChoice[0].Selected = true;
ViewBag.PatientChoice = patientChoice;
model.DateSubmitted = DateTime.Now;
if (ModelState.IsValid)
{
var spePatientEval = _mapper.Map<SPEPatientEval>(model);
var success = await _speRepo.AddSPEPatientEval(spePatientEval);
if (!success)
{
return View(model);
}
return View("Index");
}
return View(model);
}
This is all for the form AddSPEPatientEval.cshtml
#model SPEPatientEvalVM
#{
ViewData["Title"] = "AddSPEPatientEval";
}
<div class="col-md-8 m-auto">
<h1 class="text-center">Patient SPE Evaluation</h1>
<hr />
</div>
<div class="col-md-8 m-auto">
<div class="row">
<div class="col-md-12">
<form asp-controller="SPE" asp-action="AddSPEPatientEval" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="ApptId" />
<input type="hidden" asp-for="ActivityID" />
<input type="hidden" asp-for="VendorID" />
<input type="hidden" asp-for="PatientID" />
<input type="hidden" asp-for="DateSubmitted" value="#String.Format("{0:MM/dd/yyyy}", DateTime.Now)" />
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<label asp-for="OverallRating" class="control-label">As #ViewBag.Patient, rate your overall level of satisfaction with this encounter.</label>
<select asp-for="OverallRating" class="form-control"
asp-items="#(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
<span asp-validation-for="OverallRating" class="text-danger"></span>
</div>
<br />
<hr />
</div>
</div>
<br />
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<label asp-for="AppearProfessComp" class="control-label">Appeared professional competent - seemed to know what s/he was
doing; inspired my comfidence; appeared to have my interests at heart.
</b></label>
<select asp-for="AppearProfessComp" class="form-control"
asp-items="#(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
<span asp-validation-for="AppearProfessComp" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<label asp-for="EffGatheredInfo" class="control-label">Effectively gathered information - collected information in a way that
seemed organized; began with several open-ended questions and progressed through interview using a balanced ratio of open-
to closed-ended questions; summarized periodically.
</label>
<select asp-for="EffGatheredInfo" class="form-control"
asp-items="#(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
<span asp-validation-for="EffGatheredInfo" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<label asp-for="ListenActively" class="control-label">Listened actively - paid attention to both my verbal and non-verbal
cues; used facial expressions/body language to express encouragement; avoided interruptions; asked questions to make sure
s/he understood what I said.
</label>
<select asp-for="ListenActively" class="form-control"
asp-items="#(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
<span asp-validation-for="ListenActively" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<label class="control-label">Established personal rapport - introduced self warmly; verbally/non-verbally showed interest
in me as a person, not just my condition; avoided technical jargon.
</label>
<select asp-for="EstabPersRapport" class="form-control"
asp-items="#(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
<span asp-validation-for="EstabPersRapport" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<label asp-for="AppropExploreMyFeelings" class="control-label">Appropriately explored my perspective - encouraged me to
identify everything that I needed to say.
</label>
<select asp-for="AppropExploreMyFeelings" class="form-control"
asp-items="#(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
<span asp-validation-for="AppropExploreMyFeelings" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<label asp-for="AddressedMyFeelings" class="control-label">Addressed my feelings - acknowledged and demonstrated interest in my
expressed and/orunexpressed feelings and experience.
</label>
<select asp-for="AddressedMyFeelings" class="form-control"
asp-items="#(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
<span asp-validation-for="AddressedMyFeelings" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<label asp-for="MetMyNeeds" class="control-label">Met my needs - worked toward a plan which addressed both the diagnosis and
my concerns about my illness.
</label>
<select asp-for="MetMyNeeds" class="form-control"
asp-items="#(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
<span asp-validation-for="MetMyNeeds" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<label asp-for="PatientComments" class="control-label"></label>
<textarea asp-for="PatientComments" class="form-control"
placeholder="Please add any additional comments you would like to express about this examination."></textarea>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 m-auto">
<div class="form-group">
<input type="submit" value="Submit" class="btn btn-primary" />
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 m-auto">
<div class="text-center">
<a asp-action="Index">Back to List</a>
</div>
</div>
</div>
#section Scripts {
#{
await Html.RenderPartialAsync("_ValidationScriptsPartial");
}
}
Once the form is completed and all required fields are entered, if I hit the "Submit" button, I get:
This localhost page can’t be found
No webpage was found for the web
address:
https://localhost:5001/SPE/AddSPEPatientEval/18659/15129/235/4
HTTP ERROR 404
What am I missing guys? I am sure it is something that is in plain site. I am just have looked at it too long and cannot find what is going on.
What have I tried... I feel like everything. I have tried adding a route to the HttpPost statement. I have tried making sure all the model fields are not null. I do not know what else to try.
Thanks in advance for any help.
Your POST route should match the GET route:
[HttpPost("[controller]/[action]/{IDAppt}/{ActivityID}/{VendorID}/{PatientID}")]
Add [FromRoute] to the action parameters:
[HttpGet("[controller]/[action]/{IDAppt}/{ActivityID}/{VendorID}/{PatientID}")]
public async Task<IActionResult> AddSPEPatientEval([FromRoute]int IDAppt, [FromRoute] int ActivityID, [FromRoute] int VendorID, [FromRoute] int PatientID)
You should also change HttpGet to HttpPost.
I have an application which simulates a clothing site.I try to build my C# object with the data that the user writes in the form and the products they bought on the site.The products are represented by a JSON object.I use 2 classes: one for the shopping cart and one for the product.
public class Product
{
[Key]
public int id { get; set; }
public string productName { get; set; }
public string productPrice { get; set; }
public string quantity { get; set; }
}
public class ShoppingCart
{
[Key]
public int? id { get; set; }
public List<Product> productList { get; set; }
public string clientName { get; set; }
public string clientAddress { get; set; }
public string clientMail { get; set; }
}
I use a controller which has the method "Save" which uses the [FromForm] attribute.After the objects is binded from the client side I add it to my database.The problem is that I get "null" values for every property in my ShoppingCart object that is sent to the method.Moreover in my browser, the data is sent correctly to the server:
screenshot from network tab in chrome
The controller that I use looks like this:
[Route("SendItems/Save")]
[ApiController]
public class SendItemsController : Controller
{
private AppDbContext _db;
public SendItemsController(AppDbContext db)
{
_db = db;
}
[HttpPost]
[Consumes("application/json")]
public async Task<IActionResult> Save([FromForm] ShoppingCart s)
{
await _db.ShoppingCarts.AddAsync(s);
await _db.SaveChangesAsync();
return RedirectToAction("Index");
}
[HttpGet("~/ThankYou/Index")]
public IActionResult Index()
{
return View();
}
}
My html for the form is written like this:
#model ShoppingCart
<div class="form-group row">
<div class="col-4">
<label id="clienId"></label>
</div>
<div class="col-6">
<input asp-for="id" id="idClient" type="hidden" />
</div>
</div>
<div class="form-group row">
<div class="col-4">
<label id="clientProds"></label>
</div>
<div class="col-6">
<input asp-for="productList" id="inputProducts" type="hidden" />
</div>
</div>
<div class="form-group row">
<div class="col-4">
<label id="clientName"></label>
</div>
<div class="col-6">
<input asp-for="clientName" id="inputName" type="text" />
</div>
</div>
<div class="form-group row">
<div class="col-4">
<label id="clientAddress"></label>
</div>
<div class="col-6">
<input asp-for="clientAddress" id="inputAddress" type="text" />
</div>
</div>
<div class="form-group row">
<div class="col-4">
<label id="clientMail"></label>
</div>
<div class="col-6">
<input asp-for="clientMail" id="inputMail" type="text" />
</div>
</div>
<div class="form-group row">
<div class="col-3 offset-4">
<button class="btn btn-primary" id="orderB" asp-controller="SendItems" action="Save" type="submit">ORDER</button>
</div>
</div>
</form>
Also another issue is that if I don't use this piece of javascript the client is not redirected anymore to the "ThankYou" page :
var orderB = document.getElementById("orderB");
orderB.addEventListener("click", function () {
var inputName = document.getElementById("inputName").value;
var inputAddress = document.getElementById("inputAddress").value;
var inputMail = document.getElementById("inputMail").value;
var auxArray = [];
for (var i = 0; i < productsAux.length; i++) {
if (productsAux[i]!="") {
auxArray[i-1] = { "productName": productsAux[i].titlu, "productPrice": productsAux[i].pret, "quantity": localStorage.getItem(productsAux[i].titlu) };
}
}
document.getElementById("inputProducts").value = JSON.stringify(auxArray);
var shoppingCart = {
productList: auxArray,
clientName: inputName,
clientAddress: inputAddress,
clientMail: inputMail
};
$.ajax({
type: "POST",
data: JSON.stringify(shoppingCart),
url: "senditems/save",
contentType: "application/json;charset=utf-8",
})
})
Here is a demo worked:
Cart.cshtml(You need to change the bind of `productList,and then you don't need to use ajax to pass data to controller):
<form method="post" asp-controller="SendItems" asp-action="Save">
<div class="form-group row">
<div class="col-4">
<label id="clienId"></label>
</div>
<div class="col-6">
<input asp-for="id" id="idClient" type="hidden" />
</div>
</div>
<div class="form-group row">
<div class="col-4">
<label id="clientProds"></label>
</div>
<div class="col-6">
#for (var i = 0; i < Model.productList.Count(); i++)
{
<input type="hidden" asp-for="#Model.productList[i].id" />
<input type="hidden" asp-for="#Model.productList[i].productName" />
<input type="hidden" asp-for="#Model.productList[i].productPrice" />
<input type="hidden" asp-for="#Model.productList[i].quantity" />
}
</div>
</div>
<div class="form-group row">
<div class="col-4">
<label id="clientName"></label>
</div>
<div class="col-6">
<input asp-for="clientName" id="inputName" type="text" />
</div>
</div>
<div class="form-group row">
<div class="col-4">
<label id="clientAddress"></label>
</div>
<div class="col-6">
<input asp-for="clientAddress" id="inputAddress" type="text" />
</div>
</div>
<div class="form-group row">
<div class="col-4">
<label id="clientMail"></label>
</div>
<div class="col-6">
<input asp-for="clientMail" id="inputMail" type="text" />
</div>
</div>
<div class="form-group row">
<div class="col-3 offset-4">
<button class="btn btn-primary" id="orderB" type="submit" >ORDER</button>
</div>
</div>
</form>
Controller(SendItems):
[HttpPost]
public async Task<IActionResult> Save(ShoppingCart s)
{
return RedirectToAction("Index");
}
[HttpGet("~/ThankYou/Index")]
public IActionResult Index()
{
return View();
}
public IActionResult Cart()
{
ShoppingCart s = new ShoppingCart { id = 1, clientAddress = "address", clientName = "name1", clientMail = "123#123", productList = new List<Product> { new Product { id = 1, productName = "p1", productPrice = "10", quantity = "1" }, new Product { id = 2, productName = "p12", productPrice = "12", quantity = "3" } } };
return View(s);
}
result:
I have been trying to validate an input which is not properly in the model. I have the following code:
#using (Html.BeginForm("Address", "Locations", FormMethod.Post, new { id =
"mainForm" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="card shadow-sm">
<div class="card-header">
<h3 class="card-title">
Step 1
</h3>
<label>
Search for service location(s)
</label>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label for="exampleInputEmail1">Zip code: <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="ZipCode" name="ZipCode" autocomplete="off" autofocus />
#Html.ValidationMessage("ZipCode")
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="exampleInputPassword1">House number:</label>
<input type="text" class="form-control" id="HouseNumber" name="HouseNumber" />
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="exampleInputPassword1">City:</label>
<input type="text" class="form-control" id="City" name="City" />
</div>
</div>
</div>
</div>
<div class="card-footer">
<div class="row">
<div class="col-md-12">
<button class="btn btn-primary" type="submit">
<i class="fas fa-search"></i>
Search for location(s)
</button>
</div>
</div>
</div>
</div>
}
The mode is
#model PagedList.IPagedList<iCRM.Models.Address>
But the name which I gave to the input is not in the model. However the validation is not working at all. And the POST is ignoring my validation.
Can somebody help me out, what I am doing wrong?
Thanks in advance.
You have 2 options.
add ZipCode to the model class iCRM.Models.Address.
Write custom validation with Request.Forms["ZipCode"] and Javascript handler on client side. (#Html.ValidationMessage("ZipCode") you can not call)
This is idea based on option 2 but not a definite answer.
Controller
[HttpGet]
public ActionResult Address()
{
return View();
}
[HttpPost]
public ActionResult Address(AddressModel model)
{
if (String.IsNullOrEmpty(Request.Form["ZipCode"]))
{
ViewBag.ValidationForZipCode = "Problem with ZipCode";
}
return View();
}
View
#model WebApplication1.Models.AddressModel
#{
ViewBag.Title = "Address";
string strValidationForZipCode = "";
if (ViewBag.ValidationForZipCode != null)
{
strValidationForZipCode = ViewBag.ValidationForZipCode.ToString();
}
}
<h2>Address</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken();
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="pull-right">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</div>
<table>
<tr>
<td>
<div class="form-group">
#Html.LabelFor(model => model.Address1, htmlAttributes: new {
#class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Address1, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Address1, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<label for="exampleInputEmail1">Zip code: <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="ZipCode" name="ZipCode" autocomplete="off" autofocus />
<input type="hidden" id="hdValidationForZipCode" name="hdValidationForZipCode" value="#strValidationForZipCode" />
</div>
</td>
</tr>
<tr>
<td>
</td>
</tr>
</table>
</div>
}
<script type="text/javascript">
var str1 = document.getElementById("hdValidationForZipCode").value; //$('#hdValidationForZipCode').val();
if (str1 != "")
alert(str1);
</script>
Model
using System.ComponentModel.DataAnnotations;
namespace WebApplication1.Models
{
public class AddressModel
{
[Required]
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string Country { get; set; }
}
}
Part of my form Includes a number of drop-down list and fills them in the View Component section from the database.
This is my view
#page
#model Site.Web.Pages.Admin.CourseManagement.CreateModel
<div class="row">
<form method="post" asp-page="/Admin/CourseManagement/Create" enctype="multipart/form-data">
<div class="well col-md-7 col-sm-7">
<div class="form-group">
<div class="form-group">
<label asp-for="Model.CourseTitle" class="control-label"></label> :
<input asp-for="Model.CourseTitle" type="text" class="form-control" required />
<span asp-validation-for="Model.CourseTitle" class="text-danger"></span>
</div>
#await Component.InvokeAsync("FillCourseDetail")
<div class="form-group">
<label asp-for="Model.CoursePrice" class="control-label"></label> :
<input asp-for="Model.CoursePrice" class="form-control" min="1000" value="1000" placeholder="قیمت به ریال" type="number" required />
<span asp-validation-for="Model.CoursePrice" class="text-danger"></span>
</div>
<div class="form-group">
<span class="form-group glyphicon glyphicon-tags"> </span>
<input asp-for="Model.Keywordkeys" class="form-control " id="basic" data-role="tagsinput" placeholder="جداسازی تگ ها با کاما(,)" required>
</div>
</div>
<div class="form-group">
<input type="submit" class="btn glyphicon glyphicon-send" value="ذخیره اطلاعات" />
</div>
</div>
<div class="well col-md-5 col-sm-5">
<div class="form-group">
<div class="form-group">
<label asp-for="Model.UploadedImage" class="control-label"></label>
<div class="form-group">
<img class="img-responsive img-rounded" id="imgAvatar" src="~/images/UserProfile/index.png" />
</div>
<input asp-for="Model.UploadedImage" type="file" class="btn glyphicon glyphicon-open-file" required />
<span asp-validation-for="Model.UploadedImage" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Model.DemoFileName" class="control-label"></label>
<input asp-for="Model.DemoFileName" type="file" class="btn glyphicon glyphicon-open-file" required />
<span asp-validation-for="Model.DemoFileName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Model.CourseDescription" class="control-label"></label> :
<textarea asp-for="Model.CourseDescription" class="form-control total_area" type="text" required></textarea>
<span asp-validation-for="Model.CourseDescription" class="text-danger"></span>
</div>
</div>
</div>
</form>
</div>
And this is my View Component's View
#model CourseCreateVm
<div class="form-group">
<label asp-for="#Model.CourseGroupId" class="control-label"></label>
<select asp-for="#Model.CourseGroupId" class="form-control" asp-items="#(new SelectList(Model.CourseGroups, "Id", "Title"))" required><option class="text-danger">لطفا انتخاب کنید</option></select>
<span asp-validation-for="#Model.CourseGroupId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.CustomUserId" class="control-label"></label>
<select asp-for="#Model.CustomUserId" class="form-control" asp-items="#(new SelectList(Model.CustomUsers,"Id","ShowUserName"))" required><option class="text-danger">لطفا انتخاب کنید</option></select>
<span asp-validation-for="#Model.CustomUserId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.CourseLevelId" class="control-label"></label>
<select class="form-control" asp-for="#Model.CourseLevelId" asp-items="#(new SelectList(Model.CourseLevels, "Id", "Title"))"><option class="text-danger">لطفا انتخاب کنید</option></select>
<span asp-validation-for="#Model.CourseLevelId"></span>
</div>
<div class="form-group">
<label asp-for="#Model.CourseStatusId" class="control-label"></label>
<select class="form-control" asp-for="#Model.CourseStatusId" asp-items="#(new SelectList(Model.CourseStatuses, "Id", "Title"))" required><option class="text-danger">لطفا انتخاب کنید</option></select>
<span asp-validation-for="#Model.CourseStatusId"></span>
</div>
And this is the viewmodel used both in View Component and in the main view
public class CourseCreateVm
{
public virtual int? CourseStatusId { get; set; }
public List<CourseStatusVm> CourseStatuses { get; set; }
public virtual int? CourseLevelId { get; set; }
public List<CourseLevelVm> CourseLevels { get; set; }
public virtual string CustomUserId { get; set; }
public List<CustomUserVm> CustomUsers { get; set; }
public virtual int? CourseGroupId { get; set; }
public List<CourseGroupVm> CourseGroups { get; set; }
public string CourseTitle { get; set; }
public string CourseDescription { get; set; }
public decimal CoursePrice { get; set; }
public IFormFile UploadedImage { get; set; }
public IFormFile DemoFileName { get; set; }
public List<string> Keywordkeys { get; set; }
}
But when I submit the form. Selected items in the drop-downs Model Binder Cannot Bind them to the Model.
How should I solve this problem?
Try to use the name attribute of the select tag help instead of asp-for in the view component like below:
div class="form-group">
<label asp-for="#Model.CourseGroupId" class="control-label"></label>
<select name="CourseCreateVm.CourseGroupId" class="form-control" asp-items="#(new
SelectList(Model.CourseGroups, "Id", "Title"))" required><option class="text-danger">لطفا انتخاب کنید</option></select>
<span asp-validation-for="#Model.CourseGroupId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.CustomUserId" class="control-label"></label>
<select name="CourseCreateVm.CustomUserId" class="form-control" asp-items="#(new
SelectList(Model.CustomUsers,"Id","ShowUserName"))" required><option class="text-danger">لطفا انتخاب کنید</option></select>
<span asp-validation-for="#Model.CustomUserId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.CourseLevelId" class="control-label"></label>
<select name="CourseCreateVm.CourseLevelId" class="form-control" asp-items="#(new
SelectList(Model.CourseLevels, "Id", "Title"))"><option class="text-danger">لطفا انتخاب کنید</option></select>
<span asp-validation-for="#Model.CourseLevelId"></span>
</div>
<div class="form-group">
<label asp-for="#Model.CourseStatusId" class="control-label"></label>
<select name="CourseCreateVm.CourseStatusId" class="form-control" asp-items="#(new
SelectList(Model.CourseStatuses, "Id", "Title"))" required><option class="text-danger">لطفا انتخاب کنید</option></select>
<span asp-validation-for="#Model.CourseStatusId"></span>
</div>
I want to create an entity in asp.net core mvc. The entity represents an exercise workout, and it has a child collection of exercise sets:
public class Workout
{
public DateTime Date { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<Set> Sets { get; set; }
}
public class Set
{
public int Id { get; set; }
public int ExerciseId { get; set; }
public int WorkoutId { get; set; }
public decimal Weight { get; set; }
public int Reps { get; set; }
public virtual Exercise Exercise { get; set; }
public virtual Workout Workout { get; set; }
}
The form looks like this:
The "Add Set" button uses JavaScript to add a group of "set" related fields to the form, so there can be any number of "set" related fields.
Here is my existing code for the view containing the form:
#model Weightlifting.Models.Workout
#{
ViewData["Title"] = "Add Workout";
}
<h2>Add Workout</h2>
<form asp-action="Create">
<div class="form-horizontal">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Date" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Date" class="form-control" />
<span asp-validation-for="Date" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="Name" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="Description" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Description" class="form-control" />
<span asp-validation-for="Description" class="text-danger" />
</div>
</div>
<div class="form-group">
<fieldset class="form-add-set">
<label for="sets" class="col-md-2 control-label">Sets</label>
<div class="col-md-10">
<div class="add-sets">
<div class="form-inline add-set">
<div class="form-group">
<label class="control-label">Exercise</label>
<select class="form-control" asp-items="ViewBag.Exercises"></select>
</div>
<div class="form-group">
<label asp-for="Sets.First().Reps" class="control-label"></label>
<input asp-for="Sets.First().Reps" placeholder="Reps" class="form-control" />
<span asp-validation-for="Sets.First().Reps" class="text-danger" />
</div>
<div class="form-group">
<label asp-for="Sets.First().Weight" class="control-label"></label>
<input asp-for="Sets.First().Weight" class="form-control" />
<span asp-validation-for="Sets.First().Weight" class="text-danger" />
</div>
<div class="form-group">
<button class="btn btn-remove-set" data-toggle="tooltip" title="Remove Set"><span class="glyphicon glyphicon-minus"></span></button>
</div>
</div>
</div>
<button class="btn btn-add-set">Add Set</button>
</div>
</fieldset>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</div>
</div>
</form>
<div>
<a asp-action="Index"><span class="glyphicon glyphicon-arrow-left"></span> Back</a>
</div>
#section Scripts {
<script type="text/javascript">
$(document).ready(function () {
var wrapper = $('.add-sets');
$(".btn-add-set").click(function(e) {
e.preventDefault();
$('.add-set:first-child').clone(true).appendTo(wrapper);
$('.add-set .btn-remove-set').show();
});
$('.btn-remove-set').click(function (e) {
e.preventDefault();
$(this).parents('.add-set').remove();
removeButton();
});
function removeButton() {
if ($('.add-set').length == 1) {
$('.add-set .btn-remove-set').hide();
}
}
});
</script>
}
And here is the controller action that the view posts to:
public async Task<IActionResult> Create([Bind("Id,Date,Description,Name")] Workout workout)
{
// do stuff
}
My question is this: How do I code the form so that the "Sets" post to the Set collection in the workout model?
Remove the [Bind("Id,Date,Description,Name")] from your action method.
public async Task<IActionResult> Create(Workout workout)
{
// do stuff
}
Then apply indexing on your Set properties like this.
<div class="form-inline add-set">
<div class="form-group">
<label class="control-label">Exercise</label>
<select name="Sets[0].ExerciseId" class="form-control"><option value="1">Push Up</option>
<option value="1">Set Up</option>
</select>
<div class="add-sets">
<div class="form-inline add-set">
<div class="form-group">
<label class="control-label">Exercise</label>
<select name="Sets[0].ExerciseId" class="form-control" asp-items="ViewBag.Exercises"></select>
</div>
<div class="form-group">
<label asp-for="Sets.First().Reps" class="control-label"></label>
<input asp-for="Sets.First().Reps" name="Sets[0].Reps" placeholder="Reps" class="form-control" />
<span asp-validation-for="Sets.First().Reps" class="text-danger" />
</div>
<div class="form-group">
<label asp-for="Sets.First().Weight" class="control-label"></label>
<input asp-for="Sets.First().Weight" name="Workout.Sets[0].Weight" class="form-control" />
<span asp-validation-for="Sets.First().Weight" class="text-danger" />
</div>
<div class="form-group">
<button class="btn btn-remove-set" data-toggle="tooltip" title="Remove Set"><span class="glyphicon glyphicon-minus"></span></button>
</div>
</div>
</div>
When you add new row dynamically make sure the indexing number must be sequential, start at 0 and not skip any iteration.