#using(Html.BeginForm) return null values - c#

Hi im making a shopping cart and i need to register the client, in the database i have two tables one for client and one for users in a one-one relationship in my asp.net mvc i create 2 models one for the client and other for the user, and a clientViewModel how join the two models(client & users) in the view i put a #using(Html.BeginForm) where i request the client & users attributes but when i submit the form to the controller all values are null
This is the ClientViewModel
namespace TiendaRocio.Models
{
public class ClienteViewModel
{
public Cliente Cliente { get; set; }
public Usuarios Usuarios { get; set; }
}
}
This is the view
#model TiendaRocio.Models.ClienteViewModel
#{
ViewBag.Title = "Registrar";
}
<header class="page-header">
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header icono">
<a class="navbar-brand" href="~/">
<span class="glyphicon glyphicon-user" aria-hidden="true"> </span>
</a>
</div>
<h1>Registro<small> de usuarios</small></h1>
</div>
</nav>
</header>
#using (Html.BeginForm("Registro", "Ingresar", FormMethod.Post))
{
<div class="form-group">
<label>Nombre</label>
#Html.TextBoxFor(model => model.Cliente.nombre_cliente, new { #class = "form-control", placeholder = "Ingrese aqui su Nombre ", maxlength = 50 })
</div>
<div class="form-group">
<label>Apellidos</label>
#Html.TextBoxFor(model => model.Cliente.apellidos, new { #class = "form-control", placeholder = "Ingrese aqui sus apellidos", maxlength = 50 })
</div>
<div class="form-group">
<label>Dirección</label>
#Html.TextBoxFor(model => model.Cliente.direccion, new { #class = "form-control", placeholder = "Ingrese aqui su Dirección", maxlength = 50 })
</div>
<div class="form-group">
<label>Ciudad</label>
#Html.TextBoxFor(model => model.Cliente.ciudad, new { #class = "form-control", placeholder = "Ciudad", maxlength = 50 })
</div>
<div class="form-group">
<label>Estado</label>
#Html.TextBoxFor(model => model.Cliente.estado, new { #class = "form-control", placeholder = "Estado", maxlength = 50 })
</div>
<div class="form-group">
<label>Codigo Postal</label>
#Html.TextBoxFor(model => model.Cliente.codigo_postal, new { #class = "form-control", placeholder = "Ingrese aqui su Codigo Postal", maxlength = 50 })
</div>
<div class="form-group">
<label>Telefono</label>
#Html.TextBoxFor(model => model.Cliente.telefono, new { #class = "form-control", placeholder = "Ingrese aqui su Telefono", maxlength = 50 })
</div>
<div class="form-group">
<label>Nombre de Usuario</label>
#Html.TextBoxFor(model => model.Usuarios.nombre_usuario, new { #class = "form-control", placeholder = "Ingrese aqui su Nobre de Usuario", maxlength = 50 })
</div>
<div class="form-group">
<label>Contraseña</label>
#Html.TextBoxFor(model => model.Usuarios.contraseña, new { #class = "form-control", placeholder = "Ingrese aqui su contraseña", maxlength = 50 })
</div>
<div class="form-group">
<button type="submit" class="btn btn-danger">Registrar</button>
</div>
}
<div>
#Html.ActionLink("Regresar","Index","Home")
</div>
And this is the controller
public ActionResult Registro(string Nombre_Cliente,string Apellidos,string Direccion,string Ciudad,string Estado,string Codigo_Postal,string Telefono, string Nombre_Usuario, string Contraseña)
{
if (ModelState.IsValid)
{
if (modelo.registrar(new Usuarios { nombre_usuario = Nombre_Usuario, contraseña = Contraseña, permisos = 0 }))
{
if (cm.registrar(new Cliente { nombre_cliente = Nombre_Cliente, apellidos = Apellidos, direccion = Direccion, ciudad = Ciudad, estado = Estado, codigo_postal = Codigo_Postal, telefono = Telefono }))
{
return new RedirectResult("~/Home", false);
}
return new RedirectResult("Registrar", false);
}
else
{
return new RedirectResult("Registrar", false);
}
}
else
{
return new RedirectResult("Registrar", false);
}
}

Change yor controller method to
[HpptPost]
public ActionResult Registro(ClienteViewModel model)
{
....
}
and the properties of the model will be correctly bound. You generating controls for your model, so post it back!. If you inspect the html your generating you will see elements such as
<input type="text" name="Cliente.nombre_cliente" .../>
not name="nombre_cliente" so there is no posted value that would match string Nombre_Cliente
Side note: Rather than adding attributes such as maxlength = 50, use validation attributes (e.g. [StringLength] on your model properties so that you get both server and client side validation in conjunction with #Html.ValidatinMessageFor()

Related

After I did update-package in the package manager my submit button has lost is functionality and does nothing

I have a registration form and there is two inputs for password and password confirmation. When I enter distinct values I wanted it to show the error message as 'Passwords should match' or something. So I googled it and found out that update-package should fix this problem. Then I applied this solution in order to fix my problem, now, neither my error message shows up nor my submit button works.
My Registration View:
<div class="container-fluid">
#using (Html.BeginForm("Register", "User", FormMethod.Post, new { #class = "col-12" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal p-3 m-3 w-100 d-flex flex-column align-items-center">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group w-100">
<label class="form-control-label col-md-12">Kullanıcı adı</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.kullaniciAdi, new { htmlAttributes = new { #class = "form-control", #required = "required" } })
#Html.ValidationMessageFor(model => model.User.kullaniciAdi, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Firma adı</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.firmaAdi, new { htmlAttributes = new { #class = "form-control", #required = "required" } })
#Html.ValidationMessageFor(model => model.User.firmaAdi, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Şifre</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.sifre, new { htmlAttributes = new { #class = "form-control", #required = "required", #type = "password" } })
#Html.ValidationMessageFor(model => model.User.sifre, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Şifre tekrar</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.sifreTekrar, new { htmlAttributes = new { #class = "form-control", #required = "required", #type = "password" } })
#Html.ValidationMessageFor(model => model.User.sifre, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">E-mail</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.mail, new { htmlAttributes = new { #class = "form-control", #required = "required", #type = "text" } })
#Html.ValidationMessageFor(model => model.User.mail, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Telefon</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.telefon, new { htmlAttributes = new { #class = "form-control", #type = "text", #required = "required" } })
#Html.ValidationMessageFor(model => model.User.telefon, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Ülkeniz</label>
#Html.EditorFor(model => model.Address.ulkeID, new { htmlAttributes = new { #class = "form-control", #type = "text", #readonly="readonly", #Value="Türkiye" } })
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Bulunduğunuz il</label>
<select class="form-control col-md-12" name="Address.sehirID" id="il" required></select>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Bulunduğunuz ilçe</label>
<select class="form-control col-md-12" name="Address.ilceID" id="ilce" disabled required>
<option>Bir İl Seçiniz</option>
</select>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Açık adresiniz</label>
<div class="col-md-12">
#Html.EditorFor(model => model.Address.acikAdres, new { htmlAttributes = new { #class = "form-control", #type = "text", #required = "required" } })
#Html.ValidationMessageFor(model => model.Address.acikAdres, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<label class="form-control-label col-md-12">Oluşturulma Tarihi</label>
<div class="col-md-12">
#Html.EditorFor(model => model.User.olusturulmaTarihi, new { htmlAttributes = new { #class = "form-control", #type = "text", #readonly="readonly", #Value=sqlFormat } })
#Html.ValidationMessageFor(model => model.Address.acikAdres, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group w-100">
<div class="col-md-offset-2 col-md-12">
<input type="submit" value="Kaydol" class="btn btn-success" />
</div>
</div>
</div>
}
</div>
Register Action:
[HttpPost]
public ActionResult Register(RegisterVM model)
{
tblKullanici user = null;
tblAdres address = null;
if(model != null)
{
db = new DatabaseContext();
user = model.User;
address = model.Address;
db.tblKullanici.Add(user);
db.tblAdres.Add(address);
db.SaveChanges();
if (db.SaveChanges() > 0)
{
Session["login"] = model.User;
return RedirectToAction("Index", "App");
}
}
ViewBag.Message = "Kayıt işlemi sırasında hata oluştu!";
return View(model);
}
jQuery
<script>
// ajax call to bring district and city info dynamically according to the city value
$(function () {
$.ajaxSetup({
type: "post",
url: "/User/IlIlce",// target
dataType: "json"
});
$.extend({
ilGetir: function () {
$.ajax({
//sending data
data: { "tip": "ilGetir" },
success: function (sonuc) {
//check result if ok then append it to selectlist
if (sonuc.ok) {
$.each(sonuc.text, function (index, item) {
var optionhtml = '<option value="' + item.Value + '">' + item.Text + '</option>';
$("#il").append(optionhtml);
});
} else {
$.each(sonuc.text, function (index, item) {
var optionhtml = '<option value="' + item.Value + '">' + item.Text + '</option>';
$("#il").append(optionhtml);
$("body").append(optionhtml);
});
}
}
});
},
ilceGetir: function (cityID) {
$.ajax({
// then we get the districts with cityID
data: { "ilID": cityID, "tip": "ilceGetir" },
success: function (sonuc) {
// deleting records
$("#ilce option").remove();
if (sonuc.ok) {
// disabled to false
$("#ilce").prop("disabled", false);
$.each(sonuc.text, function (index, item) {
var optionhtml = '<option value="' + item.Value + '">' + item.Text + '</option>';
$("#ilce").append(optionhtml);
});
} else {
$.each(sonuc.text, function (index, item) {
var optionhtml = '<option value="' + item.Value + '">' + item.Text + '</option>';
$("#ilce").append(optionhtml);
});
}
}
});
}
});
// invoke ilGetir to get city values
$.ilGetir();
// on change in city value
$("#il").on("change", function () {
// we get the id of selected value
var cityID = $(this).val();
// and pass it to the ilceGetir function to get the districts
$.ilceGetir(cityID);
});
});
</script>
and the method that ajax call goes:
public JsonResult IlIlce(int? ilID, string tip)
{
db = new DatabaseContext();
List<SelectListItem> sonuc = new List<SelectListItem>();
bool isSuccessful = true;
try
{
switch (tip)
{
case "ilGetir":
// we assign the city values in db to sonuc(result) variable
foreach (var sehir in db.tblSehir.ToList())
{
sonuc.Add(new SelectListItem
{
Text = sehir.sehirAdi,
Value = sehir.sehirID.ToString()
});
}
break;
case "ilceGetir":
// we will fetch districts with sehirID(cityID)
foreach (var ilce in db.tblİlce.Where(il => il.bagliOlduguSehirID == ilID).ToList())
{
sonuc.Add(new SelectListItem
{
Text = ilce.ilceAdi,
Value = ilce.ilceID.ToString()
});
}
break;
default:
break;
}
}
catch (Exception e)
{
// if we encounter an error
isSuccessful = false;
sonuc = new List<SelectListItem>();
sonuc.Add(new SelectListItem
{
Text = e.Message,
Value = "Default"
});
}
// i return the results as json
return Json(new { ok = isSuccessful, text = sonuc });
}
ilce means: district
sehir/il both means: city
sifre: password
kullaniciAdi: username
telefon: phone number
ulke: country
ilGetir : fetch city
ilceGetir: fetch district
kullanici: user
adres: address
sonuc: result
tip: type

Change what submit button does based on editorFor circumstance

I have an edit form page on my website that allows users to edit quantities, on this page I used editorFor's which look like this
#Html.EditorFor(model => model.item_qty, new { htmlAttributes = new { min = 0, #class = "form-control" } })
And I have a submit button that looks like this
<input type="submit" value="Save" class="btn" />
I want to make it so that if the user increases the qty, it will go ahead and run the post method. But on the other hand, if a user was to decrease the qty, I would want the save button to look like this
<input type="submit" value="Save" onclick="confirm()" class="btn" />
Where it gets the user to confirm before running the post.
How can I make my save button change based on what the user types into the editorFor?
Here is my entire view page as requested
#model PIC_Program_1._0.Models.JODetails
#using PIC_Program_1._0.Models
#{
ViewBag.Title = "Edit";
PIC_Program_1_0Context db = new PIC_Program_1_0Context();
var currentData = db.JODetails.AsNoTracking().FirstOrDefault(j => j.ID == Model.ID);
Component comp = db.Components.Find(Model.ComponentID);
Item i = db.Items.Find(Model.ItemID);
}
<script type="text/javascript">
function clicked(e) {
if(#i != null ) {
var itemDiff = // model - new editorfor value;
if (!confirm('Are you sure? Doing this will reduce item ' + #i.ItemID + ' future stock to ' + itemDiff))e.preventDefault();
}
}
function OnChangeEvent(){
alert("value is changed");
var itemQty = $('#itemQTY').val();
if (itemQty < #Model.item_qty) {
btn.Attributes.Add("onclick", "clicked(event)");
}
}
</script>
<h2>Edit</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>JODetails</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ID)
#Html.HiddenFor(model => model.subDetail)
<p style="color:red">#ViewBag.Error</p>
<div class="form-group">
#Html.LabelFor(model => model.ItemID, "ItemID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ItemID", null, "-- Select --", htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ItemID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.item_qty, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#if (ViewBag.isValid == false)
{
#Html.TextBoxFor(model => model.item_qty, new { disabled = "disabled", #Value = Model.item_qty, #readonly = "readonly" })
}
else
{
#Html.EditorFor(model => model.item_qty, new { htmlAttributes = new { onchange = "OnChangeEvent()", min = 0, #class = "form-control" #id = "itemQTY"} })
#Html.ValidationMessageFor(model => model.item_qty, "", new { #class = "text-danger" })
}
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn"/>
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
For the on change you can on your editor for:
#Html.EditorFor(model => model.item_qty, new { htmlAttributes = new { onchange = "OnChangeEvent(this)", min = 0, #class = "form-control", #id ="someId" } })
<script type="text/javascript">
function OnChangeEvent(){
var itemQty = $('#someID').val(); //This will give you value of editor for
alert("new value is: " + itemQty);
//Call some controller function here and do your increase/decrease logic and return value so we know what to do. also perform your save in controller too if needed.
#Model.IsChanged = true;
//do other functions here also like change button
//if decrease add below
btn.Attributes.Add("onclick", "confirm()");
//if increase remove and perform save.
}
</script>
You can also change the button from that method. There is no good way to do on call events at a server level, unless using blazor, so javascript is your best bet here.
Updated answer per OP:
#model PIC_Program_1._0.Models.JODetails
#using PIC_Program_1._0.Models
#{
ViewBag.Title = "Edit";
PIC_Program_1_0Context db = new PIC_Program_1_0Context();
var currentData = db.JODetails.AsNoTracking().FirstOrDefault(j => j.ID == Model.ID);
Component comp = db.Components.Find(Model.ComponentID);
Item i = db.Items.Find(Model.ItemID);
}
<h2>Edit</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>JODetails</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ID)
#Html.HiddenFor(model => model.subDetail)
<p style="color:red">#ViewBag.Error</p>
<div class="form-group">
#Html.LabelFor(model => model.ItemID, "ItemID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ItemID", null, "-- Select --", htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ItemID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.item_qty, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#if (ViewBag.isValid == false)
{
#Html.TextBoxFor(model => model.item_qty, new { disabled = "disabled", #Value = Model.item_qty, #readonly = "readonly" })
}
else
{
#Html.EditorFor(model => model.item_qty, new { htmlAttributes = new { onchange = "OnChangeEvent(this)", min = 0, #class = "form-control", #id = "itemQTY"} })
#Html.ValidationMessageFor(model => model.item_qty, "", new { #class = "text-danger" })
}
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn"/>
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<script type="text/javascript">
function OnChangeEvent(){
alert("value is changed");
var itemQty = $('#itemQTY').val();
if (itemQty < #Model.item_qty) {
btn.Attributes.Add("onclick", "clicked(event)");
}
}
</script>

Dynamic Add and Edit of Data in Asp.net Mvc using Razor view

I'm new to MVC. Using the scaffolding mechanism I have managed to create CRUD operations on the database table. This works well with working on a single MVC Model at a time (Mapped to a single Model). I want to implement add & edit of a List into database (will be empty list initially), the user should be able to add as many number of items as he need and then submit the data to the database. I want this list to be of dynamic length, so that when user edits the data he should be able to add few more new elements into the Model also deleting few individual Model. I couldn't find proper resource to come up with a solution. Little help will be much Appreciated.
Scenario - Person can have multiple Addresses or Person will not be having any addresses. How to add multiple Address by adding addresses into the view and how to perform edit on those? If one of the Address needs to be deleted then how to do so?
Thank you.
Here is My View:
#model MVC.Models.PersonDetailsViewModel
#{
ViewBag.Title = "AddorEdit";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="container">
<div id="personDetails" class="row">
#Html.HiddenFor(model => model.personModel.PersonId, new { #id = "personId" })
<div class="form-group">
<div class="col-md-2">
<label>First Name</label>
<div style="display:inline">
#Html.EditorFor(model => model.personModel.FirstName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.personModel.FirstName, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-md-2">
<label>Last Name</label>
<div style="display:inline;">
#Html.EditorFor(model => model.personModel.LastName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.personModel.LastName, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-md-2">
<label>Date of Birth</label>
<div style="display:inline">
#Html.EditorFor(model => model.personModel.DateOfBirth, new { #id = "dob", htmlAttributes = new { #class = "form-control date-picker" } })
#Html.ValidationMessageFor(model => model.personModel.DateOfBirth, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-md-1">
<label>Height</label>
<div style="display:inline">
#Html.EditorFor(model => model.personModel.Height, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.personModel.Height, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-md-1">
<label>Weight</label>
<div style="display:inline">
#Html.EditorFor(model => model.personModel.Weight, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.personModel.Weight, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-md-2">
<label>Location</label>
<div style="display:inline">
#Html.EditorFor(model => model.personModel.Location, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.personModel.Location, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
<br />
<div id="tabs" class="panel panel-default">
<div class="panel-heading">
<ul class="nav nav-tabs">
<li class="active">Address</li>
<li>Insuarance</li>
<li>Emergency Contacts</li>
</ul><br />
</div>
<div class="tab-content panel-body">
<div id="tabs-1" class="tab-pane fade in active">
<div style="height:22px">
<a class="btn btn-default" id="btnAdd" style="float:right"><span class="glyphicon glyphicon-plus-sign"></span> Add New Row</a>
</div>
<br />
<div id="mainContent">
<div id="addressDiv">
<div class="col-md-11">
#*#Html.Partial("_Address", Model.addressModel);*#
#{
Html.RenderAction("AddressPartialView", "Person");
}
</div>
<a id="closeAddress" style="margin-top:33px" class="col-md-1 closeLink"><i class="glyphicon glyphicon-trash" style="color:red"></i></a>
</div>
</div>
</div>
<div id="tabs-2" class="tab-pane fade">
#Html.HiddenFor(model => model.insuranceModel.InsuranceId, new { #id = "insuranceId" })
<div class="col-md-4">
<label>Health Plan</label>
<div style="display:inline">
#Html.TextBoxFor(model => model.insuranceModel.HealthPlan, null, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.insuranceModel.HealthPlan, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-md-4">
<label>Health Plan Type</label>
<div style="display:inline">
#Html.TextBoxFor(model => model.insuranceModel.HealthPlanType, null, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.insuranceModel.HealthPlanType, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-md-4">
<label>Card Number</label>
<div style="display:inline">
#Html.TextBoxFor(model => model.insuranceModel.CardNumber, null, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.insuranceModel.CardNumber, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div id="tabs-3" class="tab-pane fade">
#Html.HiddenFor(model => model.emergencyContactModel.EmergencyContactId, new { #id = "emergencyContactId" })
<div class="col-md-3">
<label>Contact Patient</label>
<div style="display:inline">
#{
List<SelectListItem> personItems = new List<SelectListItem>();
personItems.Add(new SelectListItem { Text = "--Select One--", Value = "", Selected = true });
personItems.Add(new SelectListItem { Text = "1", Value = "1" });
personItems.Add(new SelectListItem { Text = "2", Value = "2" });
personItems.Add(new SelectListItem { Text = "3", Value = "3" });
personItems.Add(new SelectListItem { Text = "4", Value = "4" });
}
#Html.DropDownListFor(model => model.emergencyContactModel.ContactPersonId, personItems, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.emergencyContactModel.ContactPersonId, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-md-3">
<label>Relationship Type</label>
<div style="display:inline">
#{
List<SelectListItem> relationshipItems = new List<SelectListItem>();
relationshipItems.Add(new SelectListItem { Text = "--Select One--", Value = "", Selected = true });
relationshipItems.Add(new SelectListItem { Text = "Father", Value = "Father" });
relationshipItems.Add(new SelectListItem { Text = "Mother", Value = "Mother" });
relationshipItems.Add(new SelectListItem { Text = "Son", Value = "Son" });
relationshipItems.Add(new SelectListItem { Text = "Daughter", Value = "Daughter" });
relationshipItems.Add(new SelectListItem { Text = "Guardian", Value = "Guardian" });
}
#Html.DropDownListFor(model => model.emergencyContactModel.RelationshipType, relationshipItems, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.emergencyContactModel.RelationshipType, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-md-3">
<label>Contact Number</label>
<div style="display:inline">
#Html.TextBoxFor(model => model.emergencyContactModel.ContactNumber, null, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.emergencyContactModel.ContactNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-md-3">
<label>Email Id</label>
<div style="display:inline">
#Html.TextBoxFor(model => model.emergencyContactModel.EmailId, null, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.emergencyContactModel.EmailId, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
</div>
<br />
<div class="col-md-12">
<input type="submit" value="Save" class="btn btn-default" style="margin-top:10px" />
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
And here are my Controller Methods:
public ActionResult AddressPartialView()
{
var _model = new PersonDetailsViewModel();
return PartialView("_Address", _model.addressModel);
}
//To load the data into the form - for editing
public ActionResult AddorEdit(int id = 0)
{
if (id == 0)
{
var myModel = new PersonDetailsViewModel();
return View(myModel);
}
else
{
HttpResponseMessage responsePerson = GlobalVariables.WebApiClient.GetAsync("Person/" + id.ToString()).Result;
HttpResponseMessage responseAddress = GlobalVariables.WebApiClient.GetAsync("Address/" + id.ToString()).Result;
HttpResponseMessage responseInsurance = GlobalVariables.WebApiClient.GetAsync("Insurance/" + id.ToString()).Result;
HttpResponseMessage responseEmergencyContact = GlobalVariables.WebApiClient.GetAsync("EmergencyContact/" + id.ToString()).Result;
var personJsonString = responsePerson.Content.ReadAsStringAsync();
var deserializedPerson = JsonConvert.DeserializeObject<IEnumerable<MvcPersonModel>>(personJsonString.Result);
var addressJsonString = responseAddress.Content.ReadAsStringAsync();
var deserializedAddress = JsonConvert.DeserializeObject<IEnumerable<MvcAddressModel>>(addressJsonString.Result);
var insuranceJsonString = responseInsurance.Content.ReadAsStringAsync();
var deserializedInsurance = JsonConvert.DeserializeObject<IEnumerable<MvcInsuranceModel>>(insuranceJsonString.Result);
var emergencyContactJsonString = responseEmergencyContact.Content.ReadAsStringAsync();
var deserializedEmergencyContact = JsonConvert.DeserializeObject<IEnumerable<MvcEmergencyContactModel>>(emergencyContactJsonString.Result);
var _ViewModel = new PersonDetailsViewModel();
_ViewModel.personModel = deserializedPerson.FirstOrDefault();
_ViewModel.addressModel = deserializedAddress.FirstOrDefault();
_ViewModel.insuranceModel = deserializedInsurance.FirstOrDefault();
_ViewModel.emergencyContactModel = deserializedEmergencyContact.FirstOrDefault();
return View(_ViewModel);
}
}
//Posting data to the database
[HttpPost]
public ActionResult AddorEdit(PersonDetailsViewModel viewModel)
{
HttpResponseMessage responsePerson = GlobalVariables.WebApiClient.PostAsJsonAsync("Person", viewModel.personModel).Result;
HttpResponseMessage responseAddress = GlobalVariables.WebApiClient.PostAsJsonAsync("Address", viewModel.addressModel).Result;
HttpResponseMessage responseInsurance = GlobalVariables.WebApiClient.PostAsJsonAsync("Insurance", viewModel.insuranceModel).Result;
HttpResponseMessage responseEmergencyContact = GlobalVariables.WebApiClient.PostAsJsonAsync("EmergencyContact", viewModel.emergencyContactModel).Result;
return RedirectToAction("Index");
}
I'm using Web API for the backend process. I have added a delete and Add New Row button in the view for Address tab. For now it is working with just a single Model, I wanted to know how to implement it for a Dynamic list, So as to A Person can have 'n' number of Addresses and he can edit whichever he want and also delete based on AddressId. I know the code seems quite low rated. Just want to know the syntax and semantics on how to proceed with working on List. Sorry for Messing up things. Thank you.
Got a solution from Matt lunn.
Follow this link :-
https://www.mattlunn.me.uk/blog/2014/08/how-to-dynamically-via-ajax-add-new-items-to-a-bound-list-model-in-asp-mvc-net/
It is implemented by using custom HtmlHelper Extension and creating Html.EditorForMany().
Thanks a lot for the trick Matt Lunn. Works Exactly How I wanted. :)

Step wizard in Asp.Net MVC unintentionally validating with prev button

I'm following this guide here to create a step wizard to traverse multiple pages with forms on each while saving each forms data to store in my db but the problem I'm having is on the second page 'addressDetails'. When I press the prevBtn to return to the previous page 'basicDetails', my form is trying to do client side validation and I get all the validation errors instead of posting to my action method to see whether the prevBtn or nextBtn was pressed
Here is my addressDetails page
<div class="col-sm-7 col-sm-offset-1">
#using (Html.BeginForm("AddressDetails", "User", FormMethod.Post)) {
<div class="row">
<h3>What's the address for this payout method?</h3>
</div>
<div class="row">
<div class="form-group">
<label for="AddressLine1">Street address</label>
#Html.TextBoxFor(m => m.StreetAddressLine1, new { #id = "AddressLine1", #class = "form-control input-lg", placeholder = "e.g. 123 Main St." }) #Html.ValidationMessageFor(m => m.StreetAddressLine1,
"", new { #class = "text-danger" })
</div>
</div>
<div class="row">
<div class="form-group">
<label for="AddressLine2">Apt, suite, bldg. (optional)</label>
#Html.TextBoxFor(m => m.StreetAddressLine2, new { #id = "AddressLine2", #class = "form-control input-lg", placeholder = "e.g. Apt #6" }) #Html.ValidationMessageFor(m => m.StreetAddressLine2,
"", new { #class = "text-danger" })
</div>
</div>
<div class="row">
<div class="col-sm-6" style="padding-left: 0px; padding-right: 5px;">
<div class="form-group">
<label for="City">City</label> #Html.TextBoxFor(m => m.City, new { #id = "City", #class = "form-control input-lg" })
#Html.ValidationMessageFor(m => m.City, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-sm-6" style="padding-left: 5px; padding-right: 0px;">
<div class="form-group">
<label for="State">State / Province</label>
#Html.DropDownListFor(m => m.StateCode, new SelectList(Model.StateList, "Value", "Text"), "", new { #id = "State", #class = "btn-group-lg countryList form-control selectpicker" }) #Html.ValidationMessageFor(m
=> m.StateCode, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<label for="PostalCode">Zip code / Postal code</label>
#Html.TextBoxFor(m => m.PostalCode, new { #id = "PostalCode", #class = "form-control input-lg", placeholder = "e.g. 94102" }) #Html.ValidationMessageFor(m => m.PostalCode, "", new { #class =
"text-danger" })
</div>
</div>
<div class="row">
#Html.DropDownListFor(m => m.SelectedCountryId, new SelectList(Model.CountryList, "Value", "Text"), new { #id = "Country", #class = "btn-group-lg countryList form-control selectpicker" })
</div>
<div class="row">
<hr />
</div>
<div class="row">
<div class="col-sm-12">
<input type="submit" name="prevBtn" value='Previous' />
<input type="submit" name="nextBtn" value='Next' />
</div>
</div>
}
</div>
Here is my action method
[HttpPost]
public ActionResult AddressDetails(UserAddressViewModel addressViewModel, string prevBtn, string nextBtn)
{
YogaProfileBankAccount obj = GetBankAccount();
if (prevBtn != null)
{
UserBillingViewModel billingViewModel = new UserBillingViewModel();
//bd.CustomerID = obj.CustomerID;
//bd.CompanyName = obj.CompanyName;
return View("BasicDetails", billingViewModel);
}
if (nextBtn != null)
{
if (ModelState.IsValid)
{
//obj.Address = data.Address;
//obj.City = data.City;
//obj.Country = data.Country;
//obj.PostalCode = data.PostalCode;
return View("AccountDetails");
}
}
return View();
}
So here is what happens when I press previous, all the fields try to get validated

MVC view data passing

I am making my MVC application. My view PickGroupForHomework is redirected to by
return RedirectToAction("PickGroupForHomework", "Account", new { subject_id = id, qty=model.qty });
Of course subject_id and qty are parameters of PickGroupForHomeworkViewModel. The controller looks like this:
public ActionResult PickGroupForHomework(PickGroupForHomeworkViewModel model)
{
ClassDeclarationsDBEntities2 entities = new ClassDeclarationsDBEntities2();
model.groups = entities.Groups.ToList();
model.users = entities.Users.ToList();
int id = model.subject_id;
var subj = entities.Subjects
.Where(b => b.class_id == model.subject_id)
.FirstOrDefault();
if (subj != null)
{
model.subject_name = subj.name;
}
if (ModelState.IsValid)
{
DateTime myDate = DateTime.ParseExact(model.deadline+ " "+model.time, "yyyy-MM-dd HH:mm",
System.Globalization.CultureInfo.InvariantCulture);
ClassDeclarationsDBEntities2 entities2 = new ClassDeclarationsDBEntities2();
int total = entities2.Tasks.Count();
for (int i=0;i<model.task_names.Count;i++)
{
ClassDeclarationsDBEntities2 entities3 = new ClassDeclarationsDBEntities2();
int maxid;
if (total == 0)
{
maxid = 0;
}
else {
maxid = entities3.Tasks.Max(u => u.task_id);
}
var task = new Models.Task(model.task_names[i], model.subject_id, myDate, model.points[i], maxid + 1);
entities3.Tasks.Add(task);
entities3.SaveChangesAsync();
}
return RedirectToAction("OperationSuccess", "Account");
}
else
{
return View(model);
}
return View(model);
}
At first, everything loads correctly with correct URL including data passed from previous view. The form I am displaying now includes validation. If a user makes mistake in form, which indicades ModelState.IsValid=false, the window is reloaded. But I do not know why it is reloaded without data passed from previous window: subject_id and qty. What am I doing wrong?
EDIT:
View: #model ClassDeclarationsThsesis.Models.PickGroupForHomeworkViewModel
#{
ViewBag.Title = "Pick Group For Homework"; }
<h2>Setting homework for #Model.subject_name</h2>
#foreach (var user in Model.users) {
if (user.email.Replace(" ", String.Empty) == HttpContext.Current.User.Identity.Name)
{
if (user.user_type.Replace(" ", String.Empty) == 2.ToString()|| user.user_type.Replace(" ", String.Empty) == 3.ToString())
{
using (Html.BeginForm("PickGroupForHomework", "Account", FormMethod.Post, new { #class = "form-horizontal", enctype = "multipart/form-data" })) {
#Html.AntiForgeryToken()
<hr />
<div class="form-group">
#Html.LabelFor(model => model.deadline, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.deadline, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.deadline, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.time, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.time, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.deadline, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.file, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
<div class="editor-field">
<input type="file" name="file" />
</div>
</div>
</div>
<div class="form-group">
<table>
<tr>
<th>
Name of task
</th>
<th>
Points
</th>
</tr>
#for (int i = 0; i < Model.qty; i++)
{
<tr>
<th>
<div class="form-group">
<div class="col-md-10">
#Html.TextBoxFor(m => m.task_names[i], new { #class = "form-control" })
</div>
</div>
</th>
<th>
<div class="form-group">
<div class="col-md-10">
#Html.TextBoxFor(m => m.points[i], new { #class = "form-control" })
</div>
</div>
</th>
</tr>
}
</table>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="Submit" />
</div>
</div>
}
}
if (user.user_type.Replace(" ", String.Empty) == 1.ToString() )
{
<p>You do not have enough permissions to enter this page. Contact the administrator.</p>
}
}
}
Your problem is subject_id is not in your form, so when you post back the form it sends 0 value to the server.
you need to add a field inside form , you can add a Text or hidden field
#Html.HiddenFor(m => m.subject_id)

Categories

Resources