I am using a Dropdownlist in my modal I have it working perfectly with textboxes. I’ve tried changing my Model to multiple different properties (String, Int, SelectListItem). I feel I must be extremely close to getting this to work. I would like my validation message to appear when im using Dropdownlists as well. When the validation message is suppose to appear I get the error message ‘The ViewData item that has the key 'PartVM.IDenteredBy' is of type 'System.Int32' but must be of type 'IEnumerable'.’ Here is my View, Model, and Action.
public class UpdatePartViewModel
{
public int PartID { get; set; }
[Required]
[Display(Name = "Part Number")]
public string PartNumber { get; set; }
//[Required]
[Display(Name = "Entered By")]
public string EnteredBy { get; set; }
public SelectListItem SLIenteredBy { get; set; }
public IEnumerable<SelectListItem> EnteredByOptions { get; set; }
public int IDenteredBy { get; set; }
[Display(Name = "Date Entered")]
public DateTime DateEntered { get; set; }
[Display(Name = "Machine Types")]
public List<int> MachineTypes { get; set; }
//public string MachineTypesString { get; set; }
}
public class FindPartModel
{
[Display(Name = "Entered By")]
public string PNEnteredBy { get; set; }
public IEnumerable<SelectListItem> PNEnteredByOptions { get; set; }
public findPartNumberListAttributes[] info { get; set; }
public List<findPartNumberListAttributes> reportList { get; set; }
public UpdatePartViewModel PartVM { get; set; }
}
//PNControls.cshtml VIEW
#model Messer_PartNumbers.Models.FindPartModel
#{ HtmlHelper.UnobtrusiveJavaScriptEnabled = true; }
#Html.AntiForgeryToken()
#Html.HiddenFor(x => x.PartVM.PartID)
#Html.HiddenFor(x => x.PartVM.PartGroup)
<div class="form-group">
#Html.LabelFor(x =>x.PartVM.PartNumber, htmlAttributes: new { #class="control-label col-3" })
<div class="col-9">
#Html.TextBoxFor(x => x.PartVM.PartNumber, new { #class="form-control", #readonly="readonly" })
#Html.ValidationMessageFor(x => x.PartVM.PartNumber, "", new { #class="text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(x => x.PartVM.EnteredBy, htmlAttributes: new { #class = "control-label col-3" })
<div class="col-9">
#*#Html.TextBoxFor(x => x.PartVM.EnteredBy, new { #class="form-control" })*#
#*#Html.DropDownListFor(x => x.PartVM.SLIenteredBy, Model.PNEnteredByOptions as IEnumerable<SelectListItem>, "Select User", new { #class = "form-control" })*#
#*#Html.DropDownList("DDLenteredBy", Model.PNEnteredByOptions as IEnumerable<SelectListItem>, new { #class="form-control" })*#
#Html.DropDownListFor(x => x.PartVM.IDenteredBy, Model.PNEnteredByOptions as IEnumerable<SelectListItem>, "Select User", new { #class = "form-control" })
#*#Html.ValidationMessageFor(x => x.PartVM.EnteredBy, "", new { #class = "text-danger" })*#
#*#Html.ValidationMessageFor(x => x.PartVM.SLIenteredBy, "", new { #class = "text-danger" })*#
#Html.ValidationMessageFor(x => x.PartVM.IDenteredBy, "", new { #class = "text-danger" })
</div>
</div>
#using (Ajax.BeginForm("PartNumberUpdate", "Parts", new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "PartNumControls", OnSuccess = "ajaxPartUpdate" }))
{
<div class="modal" id="modalPNUpdate" tabindex="-1" role="dialog" aria-labelledby="lblPNUpdate" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">Part Number Details</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" id="PartNumControls">
#Html.Partial("PNControls")
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
<input type="submit" class="btn btn-primary" value="Save" />
</div>
</div>
</div>
</div>
}
[HttpPost]
[ValidateAntiForgeryToken]
[HandleError]
public ActionResult PartNumberUpdate(FindPartModel model)
{
if (ModelState.IsValid)
{
var partNumber = context.PartNumbers.Where(x => x.PartNumber1 == model.PartVM.PartNumber).FirstOrDefault();
// Updating the Parts data with the new Models Information.
partNumber.PartNumber1 = model.PartVM.PartNumber;
partNumber.PartGroup = model.PartVM.PartGroup != null ? model.PartVM.PartGroup : partNumber.PartGroup;
partNumber.Last4Number = model.PartVM.Last4Numbers;
//var str = Request.Form["DDLenteredBy"];
//if(model.PartVM.EnteredBy != null)
//{ var enteredByID = context.Employees.Where(e => e.Name == model.PartVM.EnteredBy).Select(x => x.ID).FirstOrDefault();
// partNumber.EnteredBy = enteredByID; }
/* testvar2 = testVar1 != null ? testvar1 : testvar2; || testVar2 = testVar1 ?? testVar2 */
partNumber.EnteredBy = model.PartVM.IDenteredBy;
partNumber.DateEntered = model.PartVM.DateEntered;
/// UPDATE PartNumber Record
context.Entry(partNumber).State = EntityState.Modified;
context.SaveChanges();
ViewBag.ValidMessage = "PartNumber Record Updated";
string returnStr = "refresh";
ModelState.Clear();
return Json(returnStr);
}
TempData["ErrorState"] = "x";
return PartialView("PNControls", model);
}
public ActionResult PNControls()
{
return View(new FindPartModel());
}
I needed to repopulate my Dropdownlists when the ModelState was invalid.
Now my validation with ajax works exactly as expected. I needed this at the end of my PartNumberUpdate Action.
}
/// Populate DropDownLists in Modal to UPDATE fields
var fetcher = new DataFetcher();
model.PNEnteredByOptions = fetcher.EnteredByInfo();
//ViewBag.DDLenteredby = fetcher.EnteredByInfo();
model.PNMachineTypeOptions = fetcher.machineTypeInfo();
model.PNSoftwareTypeOptions = fetcher.softwareTypeInfo();
model.PNManufacturerOptions = fetcher.manufactuerInfo();
model.PNUsageOptions = fetcher.usageInfo();
model.PNUnitsOptions = fetcher.unitsInfo();
TempData["ErrorState"] = "x";
return PartialView("PNControls", model);
}
Related
I have View with two dropdownlists first with product category and second depends on selected category list of products. When click save button and ajax redirect to Post AddOrEditPartial in controller my model object has only autogenerated Id and CreateAt. All other data from dropdowns and quantity field are null.I cant find where is the problem. Can somebody help?
public class Warehouse : BaseEntity
{
[Required(ErrorMessage = "Category Required")]
public string IdCategory { get; set; }
[Required(ErrorMessage = "Product Required")]
public string IdProduct { get; set; }
[Required(ErrorMessage = "Quantity required")]
public int Quantity { get; set; }
}
public class WarehouseViewModel
{
public Warehouse Warehouse { get; set; }
public IEnumerable<ProductCategory> ProductCategories1 { get; set; }
public IEnumerable<Product> Products { get; set; }
}
IndexView
#using (Ajax.BeginForm("AddOrEditPartial", "Warehouse", new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "formsubmit", OnSuccess = "closePopUp(data)" }))
{
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Product</h4>
</div>
<div class="modal-body" id="modbody">
#Html.Partial("AddOrEditPartial")
</div>
</div>
</div>
</div>
}
PartialView
#model MyShop.Core.ViewModels.WarehouseViewModel
<div class="panel-group">
<div class="panel-default">
<div class="panel panel-success">
<div class="panel-heading">Succes Implement Add/Edit Button</div>
<div class="panel-body" id="panbody">
<div class="col-sm-12">
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Warehouse.Id)
<div class="form-group">
#Html.LabelFor(model => model.Warehouse.IdCategory, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Warehouse.IdCategory, new SelectList(Model.ProductCategories1, "Category", "Category"), "Please select Category", new { #class = "form-control" })
#*#Html.DropDownListFor(model => model.Warehouse.Category, (IEnumerable<SelectListItem>)new SelectList(ViewBag.Cat, "Category", "Category"), "Please select Category", new { #class = "form-control" })*#
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Warehouse.IdProduct, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Warehouse.IdProduct, (IEnumerable<SelectListItem>)new SelectList(ViewBag.Prod, "Name", "Name"), "Please Select Product", new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Warehouse.Quantity, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Warehouse.Quantity, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Warehouse.Quantity, "", 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 btn-success" id="btnSubmit" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="~/Scripts/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#Warehouse_IdCategory").change(function () {
var prodId = $(this).val();
console.log(prodId);
//debugger
$.ajax({
type: "GET",
url: '#Url.Action("GetProductList", "Warehouse")/' +prodId,
data: { prodId: prodId },
contentType: "html",
success: function (response) {
//debugger
$("#Warehouse_IdProduct").empty();
$("#Warehouse_IdProduct").append(response);
}
})
})
})
</script>
Controller
public ActionResult Index()
{
WarehouseViewModel whViewModel = new WarehouseViewModel();
whViewModel.Warehouse = new Warehouse();
whViewModel.ProductCategories1 = productCategories.Collection();
whViewModel.Products = contextProduct.Collection();
return View(whViewModel);
}
[HttpPost]
public ActionResult AddOrEditPartial(Warehouse wh)
{
if (!ModelState.IsValid)
{
return Json(new { success = false });
}
else
{
var data = context.Find(wh.Id);
if (data != null)
{
data.IdProduct = wh.IdProduct;
data.IdCategory = wh.IdCategory;
data.Quantity = wh.Quantity;
context.Commit();
}
else
{
context.Insert(wh);
context.Commit();
}
return Json(new { success = true });
}
}
Change type of your IdCategory & IdProduct to int and it should work.
public class Warehouse : BaseEntity
{
[Required(ErrorMessage = "Category Required")]
public int IdCategory { get; set; }
[Required(ErrorMessage = "Product Required")]
public int IdProduct { get; set; }
[Required(ErrorMessage = "Quantity required")]
public int Quantity { get; set; }
}
#UmairZafar
public class ProductCategory : BaseEntity
{
[Required(ErrorMessage="Please fill category")]
public string Category { get; set; }
}
public class Product : BaseEntity
{
[StringLength(20)]
[DisplayName("Product Name")]
[Required(ErrorMessage = "Please fill product name")]
public string Name { get; set; }
[DataType(DataType.MultilineText)]
public string Description { get; set; }
[Range(0,1000)]
public decimal Price { get; set; }
public string Category { get; set; }
public string Image { get; set; }
}
public abstract class BaseEntity
{
public string Id { get; set; }
public DateTimeOffset CreatedAt { get; set; }
public BaseEntity()
{
Id = Guid.NewGuid().ToString();
CreatedAt = DateTime.Now;
}
}
I've tryed to merge my create and edit actions into a save action, but for some reason, when I try to insert a new Cliente, the modelState trys to validate de ID colum. If I comment out the hidden field ID in the view, it works.
Would you give me a clue, please!?
View
#model WebApplicationCursoASPNET_V3.ViewModels.FormularioClienteViewModel
#{
ViewBag.Title = "Novo";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2> Cliente</h2>
#using (#Html.BeginForm("Gravar", "Cliente"))
{
<div class="form-group">
#Html.LabelFor(m => m.cliente.Nome)
#Html.TextBoxFor(m => m.cliente.Nome, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.cliente.Nome, "", new { #class = "text-danger" })
</div>
<div class="form-group">
#Html.LabelFor(m => m.cliente.TipoAssinaturaId)
#Html.DropDownListFor(m => m.cliente.TipoAssinaturaId, new SelectList(Model.tiposAssinatura, "Id", "Nome"), "<< Selecione a assinatura >>", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.cliente.TipoAssinaturaId, "", new { #class = "text-danger" })
</div>
<div class="form-group">
#Html.LabelFor(m => m.cliente.Aniversario)
#Html.TextBoxFor(m => m.cliente.Aniversario, "{0:d}", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.cliente.Aniversario)
</div>
<div class="checkbox">
<label>
#Html.CheckBoxFor(m => m.cliente.EstaInscritoEmAssinaturas) Está inscrito em assinaturas
</label>
</div>
#Html.HiddenFor(m => m.cliente.Id)
#Html.ValidationMessageFor(m => m.cliente.Id, "", new {#class="text-danger"})
<br>
<button type="submit" class="btn btn-primary">Gravar</button>
}
Controller
[HttpPost]
public ActionResult Gravar(FormularioClienteViewModel dadosFormulario)
{
if (dadosFormulario.cliente.Id == 0)
{
if (ModelState.IsValid)
{
_context.Clientes.Add(dadosFormulario.cliente);
_context.SaveChanges();
return RedirectToAction("Index", "Cliente");
}
var vwModel = new FormularioClienteViewModel
{
cliente = dadosFormulario.cliente,
tiposAssinatura = _context.TipoAssinaturas.OrderBy(m => m.Nome).ToList()
};
return View("Form", vwModel);
}
var clienteDB = _context.Clientes.SingleOrDefault(c => c.Id == dadosFormulario.cliente.Id);
if (clienteDB == null)
{
return HttpNotFound();
}
clienteDB.Nome = dadosFormulario.cliente.Nome;
clienteDB.TipoAssinaturaId = dadosFormulario.cliente.TipoAssinaturaId;
clienteDB.Aniversario = dadosFormulario.cliente.Aniversario;
clienteDB.EstaInscritoEmAssinaturas = dadosFormulario.cliente.EstaInscritoEmAssinaturas;
_context.SaveChanges();
return RedirectToAction("Index", "Cliente");
}
Model
public class Cliente
{
public int Id { get; set; }
[Display(Name = "Nome do cliente")]
[Required]
[StringLength(255,ErrorMessage = "Tamanho máximo de 255 caracteres")]
public string Nome { get; set; }
[Display(Name = "Está inscrito em assinaturas")]
public bool EstaInscritoEmAssinaturas { get; set; }
public TipoAssinatura TipoAssinatura { get; set; }
[Display(Name = "Tipo de assinatura")]
public int TipoAssinaturaId { get; set; }
public DateTime? Aniversario { get; set; }
}
Error msg: O campo Id é obrigatório. / Field Id is required
Ideally, it is recommended to use different calls for save and update with different DTO.
In your case, now you need to make Id nullable and validate it with custom logic in Update.
public int? Id { get; set; }
So I have some custom validation implemented to prevent similar records being entered into the db. The only problem I have is that it is not presenting the user an error/validation message but rather an error page.
Where am I going wrong? Or how do I correctly implement this?
Validation:
public class ValidSimilarRequests : ValidationAttribute
{
private LotusWorksEntities db = new LotusWorksEntities();
protected override ValidationResult
IsValid(object value, ValidationContext validationContext)
{
var model = (Models.HolidayRequestForm)validationContext.ObjectInstance;
int empID = Convert.ToInt32(model.EmployeeID);
DateTime _startdate = Convert.ToDateTime(model.StartDate);
DateTime _finishdate = Convert.ToDateTime(model.FinishDate);
var holidayexist = db.HolidayRequestForms.Any( x => x.EmployeeID==empID && x.StartDate <= _startdate && x.FinishDate >= _finishdate );
if (holidayexist)
{
return new ValidationResult
("A holiday Request for this date range has already been requested");
}
else
{
return ValidationResult.Success;
}
}
}
Model:
public partial class HolidayRequestForm
{
public int RequestID { get; set; }
[ValidSimilarRequests(ErrorMessage =
"A holiday Request for this date range has already been requested")]
public int EmployeeID { get; set; }
[ValidSameWeek(ErrorMessage =
"Holiday Request Must be made on a weekly Period")]
[DisplayFormat(DataFormatString = "{0:dd/MMM/yy}", ApplyFormatInEditMode = true)]
public System.DateTime StartDate { get; set; }
[ValidStartFinishDate(ErrorMessage =
"Finish Date can not be Greater than Start date.")]
[DisplayFormat(DataFormatString = "{0:dd/MMM/yy}", ApplyFormatInEditMode = true)]
public System.DateTime FinishDate { get; set; }
[Range(0.0001, int.MaxValue, ErrorMessage = "Hours Requested must be greater than zero. ")]
public decimal HoursTaken { get; set; }
public string Comments { get; set; }
public int YearCreated { get; set; }
public int MonthCreated { get; set; }
public int DayCreated { get; set; }
public Nullable<int> YearOfHoliday { get; set; }
public Nullable<bool> Approved { get; set; }
public string SubmittedBy { get; set; }
public string ApprovedBy { get; set; }
public Nullable<int> WorkWeek { get; set; }
public Nullable<int> MonthOfHoliday { get; set; }
public virtual Employee Employee { get; set; }
}
The Error Page shows:
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
Controller:
[Authorize(Roles = "Admin,User,SuperUser")]
public ActionResult Create()
{
ViewBag.EmployeeID = new SelectList(db.Employees, "EmployeeID", "FullName");
return View();
string name = Session["Name"].ToString();
var EmployeeIDCatch = db.Employees.Where(s => s.Email.Equals(name)).Select(s => s.EmployeeID);
}
// POST: HolidayRequestForms/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "RequestID,StartDate,FinishDate,HoursTaken,Comments,YearCreated,MonthCreated,DayCreated,YearOfHoliday,Approved,SubmittedBy,ApprovedBy")] HolidayRequestForm holidayRequestForm)
{
if (ModelState.IsValid)
{
if (Session["Name"] == null)
{
TempData["msg"] = "Your Session Expired - Please Login";
return RedirectToAction("Login", "Account");
}
string name = Session["Name"].ToString();
var employeeID = db.Employees.Where(s => s.Email.Equals(name)).Select(s => s.EmployeeID).FirstOrDefault();
holidayRequestForm.EmployeeID = employeeID;
var submittedby = db.Employees.Where(s => s.Email.Equals(name)).Select(s => s.Email).FirstOrDefault();
holidayRequestForm.SubmittedBy = submittedby;
//Saves changes and begins Email Actions
db.HolidayRequestForms.Add(holidayRequestForm);
db.SaveChanges();
SendMailToAreaManager();
SendMailToManager();
SendMailToAdmin();
return RedirectToAction("Index", "Calendar");
}
ViewBag.EmployeeID = new SelectList(db.Employees, "EmployeeID", "FullName", holidayRequestForm.EmployeeID);
return View(holidayRequestForm);
}
VIEW:
#model HolidayTracker.Models.HolidayRequestForm
<div>
<div class="col-md-12">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<h2 align="center">Holiday Request Form</h2>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.StartDate, "Start Date", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.StartDate, "Start Date", new { htmlAttributes = new { #class = "form-control", #style = "width:400px", autocomplete = "off" } })
#Html.ValidationMessageFor(model => model.StartDate, "", new { #class = "text-warning" })
<p id="warning" style="color:orange"></p>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FinishDate, "Finish Date", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.FinishDate, new { htmlAttributes = new { #class = "form-control",#style = "width:400px", autocomplete = "off" } })
#Html.ValidationMessageFor(model => model.FinishDate, "", new { #class = "text-danger" })
<p id="warningFD" style="color:orange"></p>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.HoursTaken, "Hours Requested", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.HoursTaken, new { htmlAttributes = new { #class = "form-control", #style = "width:400px" } })
#Html.ValidationMessageFor(model => model.HoursTaken, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Comments, htmlAttributes: new { #class = "control-label col-md-2"})
<div class="col-md-10">
#Html.TextAreaFor(
model => model.Comments,
new { placeholder = "Enter Dates and how many Hours per Date Here. ", style = "width: 400px; height: 200px;" })
#Html.ValidationMessageFor(model => model.Comments, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Submit" class="btn btn-warning" />
</div>
</div>
}
</div>
</div>
</div>
I want to pack my data in form with foreign key and send that to database.I collect data from database with controller and show in my view and when I complete the form can not send that to database and see the exception
my controller code is
public ActionResult Register()
{
testContext test = new testContext();
List<SelectListItem> listselecteditem = new List<SelectListItem>();
foreach (Gender item in test.genders)
{
SelectListItem selectlist = new SelectListItem()
{
Text = item.GenderType,
Value = item.GenderID.ToString(),
};
listselecteditem.Add(selectlist);
}
ViewBag.Datalist = new SelectList(listselecteditem, "Value", "Text");
return View();
}
this controller get data from database and send to dropdownlist
and this controller save my data in database
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Register(Person p)
{
using (testContext test=new testContext())
{
if (ModelState.IsValid)
{
try
{
test.persons.Add(p);
test.SaveChanges();
ViewBag.Message="Success";
}
catch (Exception ec)
{
ViewBag.Message = ec.Message;
}
}
}
return View(p);
}
this is my view
#model testmvc.Models.Person
<div class="container">
<div class="row">
<div class="pull-right col-sm-offset-3 col-sm-6">
<div class="panel panel-default">
<div class="panel-heading ">
<p>register</p>
</div>
<div class="panel-body">
#using (Html.BeginForm("Register", "RegisterLogin", FormMethod.Post, new { #class = "form-horizontal" }))
{
#Html.ValidationSummary(true)
<fieldset>
#Html.AntiForgeryToken()
#if (ViewBag.Messsage != null)
{
<div class="alert alert-success">
<p>#ViewBag.Message</p>
</div>
}
<div class="form-group">
#Html.TextBoxFor(model => model.Fullname, new { #class = "form-control", #placeholder = "Full name" })
</div>
<div class="form-group">
#Html.TextBoxFor(model => model.Username, new { #class = "form-control input-sm", #id = "last_name", #placeholder = "Username" })
</div>
<div class="form-group">
#Html.TextBoxFor(model => model.EmailAddress, new { #class = "form-control input-sm", #id = "email", #placeholder = "Email address" })
</div>
<div class="form-group">
#Html.TextBoxFor(model => model.Password, new { #class = "form-control input-sm floatlabel", #id = "first_name", #placeholder = "Password" })
</div>
<div class="form-group">
#Html.TextBoxFor(model => model.Comfirmpassword, new { #class = "form-control input-sm", #id = "last_name", #placeholder = "confirmpassword" })
</div>
<div class="form-group">
#*<select>
#foreach (var item in ViewBag.DataList)
{
<option>#item.Text</option>
}
</select>*#
#Html.DropDownList("Datalist",String.Empty)
</div>
<div class="form-group">
#Html.TextBoxFor(model => model.Birthday, new { #class = "form-control input-sm", #id = "password_confirmation", #placeholder = "Birthday yyyy/dd/mm" })
</div>
<div>
<input type="submit" value="Register" class="btn btn-primary">
</div>
</fieldset>
}
</div>
</div>
</div>
</div>
</div>
and my model code
public partial class Person
{
[Key]
public int personID { get; set; }
[Required]
public String Fullname { get; set; }
[Required]
public String Username { get; set; }
[Required]
public String Password { get; set; }
[Required]
[NotMapped]
public String Comfirmpassword { get; set; }
[Required]
public String EmailAddress { get; set; }
[DataType(DataType.DateTime)]
[Required]
public DateTime Birthday { get; set; }
public int GenderID { get; set; }
[ForeignKey("GenderID")]
public virtual Gender Gender { get; set; }
}
[Table("Gender")]
public partial class Gender
{
[Key]
public int GenderID { get; set; }
[Required]
public String GenderType { get; set; }
public virtual ICollection<Person> Persons { get; set; }
}
this exception said there is not any viewdata key with "Datalist". how can I solve that and what is my code problem
The reason you are getting this exception is because inside [HttpPost] action you didn't populate the ViewBag.Datalist property, the way you did in your Get action. Since you redisplay the same view and this view requires this information in order to properly render the dropdown, you will need to populate it. To avoid repetition you could place this logic in a separate method:
private SelectList GetGenders()
{
using (testContext test = new testContext())
{
List<SelectListItem> listselecteditem = new List<SelectListItem>();
foreach (Gender item in test.genders)
{
SelectListItem selectlist = new SelectListItem()
{
Text = item.GenderType,
Value = item.GenderID.ToString(),
};
listselecteditem.Add(selectlist);
}
return new SelectList(listselecteditem, "Value", "Text");
}
}
which you are going to call in your 2 actions:
public ActionResult Register()
{
ViewBag.Datalist = GetGenders();
return View();
}
and:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Register(Person p)
{
using (testContext test = new testContext())
{
if (ModelState.IsValid)
{
try
{
test.persons.Add(p);
test.SaveChanges();
ViewBag.Message = "Success";
}
catch (Exception ec)
{
ViewBag.Message = ec.Message;
}
}
}
ViewBag.Datalist = GetGenders();
return View(p);
}
I'm using begincollectionitem component, and when trying to save data is giving error at line db.SaveChanges();. I use MVC 4 e Razor.
This message error:
The operation failed: The relationship could not be changed because
one or more of the foreign-key properties is non-nullable. When a
change is made to a relationship, the related foreign-key property is
set to a null value. If the foreign-key does not support null values,
a new relationship must be defined, the foreign-key property must be
assigned another non-null value, or the unrelated object must be
deleted.
A minha implementação é esta:
Model
public class ProdutoPadrao : IEntidadeBase
{
[Key]
public int ProdutoPadraoID { get; set; }
[Display(Name = "Descrição")]
public string Descricao { get; set; }
[Display(Name = "Detalhe")]
public string Detalhe { get; set; }
public virtual ICollection<ProdutoPadraoCaracteristica> ListaProdutoCaracteristica { get; set; }
}
public class ProdutoPadraoCaracteristica : IEntidadeBase
{
[Key]
public int ProdutoPadraoCaracteristicaID { get; set; }
public int ProdutoPadraoID { get; set; }
public string Descricao { get; set; }
public int TipoCaracteristicaID { get; set; }
[ForeignKey("ProdutoPadraoID")]
public virtual ProdutoPadrao ProdutoPadrao { get; set; }
}
Controller GET
[ControleDeAcesso(TipoAcao.Normal)]
[Authorize]
public ActionResult Detalhar(int id)
{
using (var db = new ERPContext())
{
var produtoPadrao = db.ProdutoPadrao.Include("ListaProdutoCaracteristica").Where(w => w.ProdutoPadraoID == id).ToList().FirstOrDefault();
var retorno = EntidadeBaseExt.ValidarRegistro(produtoPadrao, TipoAcao.Visualizar);
if (retorno != "")
{
TempData["MsgRetornoError"] = retorno;
return RedirectToAction("Index", "Home");
}
ViewBag.ListaCaracteristica = new SelectList(ListagemPadrao.ListaTipoCaracteristica(), "Key", "Texto");
ViewBag.ListaUnidadeMedida = new SelectList(db.UnidadeMedida.ToListERP().Select(l => new ItemLPesquisa { Key = l.UnidadeMedidaID, Texto = l.Descricao }).ToArray(), "Key", "Texto");
return View(produtoPadrao);
}
}
Controller POST
[Authorize]
[HttpPost]
[ControleDeAcesso(TipoAcao.Normal)]
public ActionResult Detalhar(string btnSubmit, ProdutoPadrao model)
{
if (!ModelState.IsValid)
{
return View(model);
}
using (var db = new ERPContext())
{
var produtoPadrao = db.ProdutoPadrao.Include("ListaProdutoCaracteristica").Where(w => w.ProdutoPadraoID == model.ProdutoPadraoID).ToList().FirstOrDefault();
var retorno = FlexGestor.Helpers.EntidadeBaseExt.ValidarRegistro(produtoPadrao, TipoAcao.Gravar);
if (retorno != "")
{
TempData["MsgRetornoError"] = retorno;
return RedirectToAction("Index", "Home");
}
if (btnSubmit != "Excluir")
UpdateModel(produtoPadrao);
FlexGestor.Helpers.EntidadeBaseExt.AtribuirValores(produtoPadrao, btnSubmit);
db.Entry(produtoPadrao).State = EntityState.Modified;
db.SaveChanges();
if (btnSubmit == "Excluir")
return RedirectToAction("Index", controller);
return RedirectToAction("Detalhar", controller, new { id = model.ProdutoPadraoID });
}
}
View
#model FlexGestor.Models.ProdutoPadrao
#using (Html.BeginForm())
{
<div class="row">
#Html.TituloPagina("Visualizando Produto Padrão", "Clique para abrir a ajuda", "#help_produtoPadrao")
#Html.HiddenFor(m => m.ProdutoPadraoID)
<div class="col-md-12">
#Html.LabelFor(m => m.Descricao) #Html.ValidationMessageFor(m => m.Descricao)
#Html.TextBoxFor(m => m.Descricao, new { #class = "form-control" })
</div>
<div class="col-md-12">
#Html.LabelFor(m => m.Detalhe) #Html.ValidationMessageFor(m => m.Detalhe)
#Html.TextAreaFor(m => m.Detalhe, new { #class = "form-control", #rows = "4" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ListaProdutoCaracteristica)
<div class="controls">
<ul id="PhonesEditor" style="list-style-type: none">
#if (Model.ListaProdutoCaracteristica != null)
{
foreach (var item in Model.ListaProdutoCaracteristica)
{
Html.RenderPartial("_CustomerPhonesEditor", item);
}
}
</ul>
</div>
<p><a id="addAnother" class="small-button">AddPhone</a></p>
</div>
<div class="row">
<div class="col-md-12">
#Html.BotaoTelaDetalhar()
</div>
</div>
}
View Detail
#model FlexGestor.Models.ProdutoPadraoCaracteristica
#using (Html.BeginCollectionItem("ListaProdutoCaracteristica"))
{
#Html.HiddenFor(m => m.ProdutoPadraoID)
#Html.HiddenFor(m => m.ProdutoPadraoCaracteristicaID)
<div class="col-md-3">
#Html.LabelFor(m => m.TipoCaracteristicaID) #Html.ValidationMessageFor(m => m.TipoCaracteristicaID)
#Html.DropDownList("TipoCaracteristicaID", (SelectList)ViewBag.ListaCaracteristica, String.Empty,
new { #class = "form-control" })
</div>
<div class="col-md-9">
#Html.LabelFor(m => m.Descricao) #Html.ValidationMessageFor(m => m.Descricao)
#Html.TextBoxFor(m => m.Descricao, new { #class = "form-control" })
</div>
<div class="form-group">
<div class="controls">
<a onclick="$(this).parent().parent().parent().remove();" class="small-button" style="float: left;">Delete</a>
</div>
</div>
}
The below line is causing the problem
model.ListaProdutoCaracteristica = null;
It would cause the below property to be null, but it is not a nullable type
public int ProdutoPadraoID { get; set; }
If you want to be able to orphan records in this way, then you need to change it to a nullable int:
public int? ProdutoPadraoID { get; set; }