ModelState missing values - c#

i am trying to create a Menu for diffent Roles but when i choose the menu and role to create a Role_has_menu something is missing and ModelState said valid = false.
This is the method i am using
public IActionResult Create()
{
ViewData["MenuID"] = new SelectList(_context.Menu, "ID", "FullName");
ViewData["RoleID"] = new SelectList(_context.Role, "ID", "Name");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID,MenuID,RoleID")] RoleHasMenu roleHasMenu)
{
if (ModelState.IsValid)
{
_context.Add(roleHasMenu);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["MenuID"] = new SelectList(_context.Menu, "ID", "FullName", roleHasMenu.MenuID);
ViewData["RoleID"] = new SelectList(_context.Role, "ID", "Name", roleHasMenu.RoleID);
return View(roleHasMenu);
}
Those are my models
public class Menu
{
public int ID { get; set; }
[Required(ErrorMessage = "The element {0} can't be empty")]
public string Controller { get; set; }
[Required(ErrorMessage = "The element {0} can't be empty")]
public string Action { get; set; }
[Required(ErrorMessage = "The element {0} can't be empty")]
public string Label { get; set; }
[InverseProperty("RoleHasMenu")]
List<RoleHasMenu> roleHasMenu { get; set; }
[NotMapped]
public string FullName { get => Controller + " - " + Action; }
}
public class Role
{
public int ID { get; set; }
[Required(ErrorMessage = "The element {0} can't be empty")]
[NotNull]
public string Name { get; set; }
[MaxLength(100, ErrorMessage = "This element can't be bigger than 100 characters")]
public string Description { get; set; }
[InverseProperty("UserAccount")]
List<UserAccount> userAccount { get; set; }
[InverseProperty("RoleHasMenu")]
List<RoleHasMenu> roleHasMenu { get; set; }
}
public class RoleHasMenu
{
[Key]
public int ID { get; set; }
[ForeignKey("MenuID")]
public Menu Menu { get; set; }
public int MenuID { get; set; }
[ForeignKey("RoleID")]
public Role Role { get; set; }
public int RoleID { get; set; }
}
and this is my problem
I have the same code in other project and it works but this time i am using Visual Studio EF6 and a MySQL database instead of SQLserver
Thanks for your time

Related

Need to compare value from other table

I have 3 classes in my model
Model
public class Student
{
public int id { get; set; }
[Required]
[DisplayName("Student Name")]
public string Name { get; set; }
[Required]
public int RollNO { get; set; }
public DateTime EnrollmentDate { get; set; }
public ICollection<Record> Records { get; set; }
}
public class Record
{
public int Id { get; set; }
public int StudentId { get; set; }
public int SubjectId { get; set; }
[Required]
public int Marks { get; set; }
public string Result { get; set; }
public virtual Student Students { get; set; }
public virtual Subject Subjects { get; set; }
}
public class Subject
{
public int id { get; set; }
[Required]
public string Title { get; set; }
[Required]
[DisplayName("Minimum Marks")]
public int MinMarks { get; set; }
[Required]
[DisplayName("Max Marks")]
public int MaxMarks { get; set; }
public ICollection<Record> Records { get; set; }
}
In subject table i will be creating each subject and setting its minimum and maximum marks required to pass...now in record table (Create Page) i want to compare the selected subject minimum marks with Record.Marks and if its less the minimum marks get Fail in Record.Result and if its greater then maximum marks get Pass in Record.Result...and i also want to compare the Result.Marks property with Subject.MaxMarks and if its greater then Subject.MaxMarks the user should get error in any form possible...
this is my controller
Controller
public ActionResult Create([Bind(Include = "Id,StudentId,SubjectId,Marks,Result")] Record record,Subject subject)
{
var selectedSubject = db.Subjects.Where(sub => subject.id == record.SubjectId).FirstOrDefault();
if (record.Marks < selectedSubject.MinMarks)
{
record.Result = "Fail";
}
else
record.Result = "Pass";
if (ModelState.IsValid)
{
db.Records.Add(record);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.StudentId = new SelectList(db.Students, "id", "Name", record.StudentId);
ViewBag.SubjectId = new SelectList(db.Subjects, "id", "Title", record.SubjectId);
return View(record);
}
Assuming your view has the input element to select/enter the subject id and the element's name attribute value is SubjectId and it is inside the form
Just add an else if to check max mark as well. You do not need the second parameter in your action method. Just remove it.
var selectedSubject = db.Subjects.FirstOrDefault(a=> a.id == record.SubjectId);
if(selectedSubject!=null)
{
if (record.Marks < selectedSubject.MinMarks)
{
record.Result = "Fail";
}
else if (record.Marks > selectedSubject.MaxMarks)
{
record.Result = "Error";
}
else
{
record.Result = "Pass";
}
}
else
{
ModelState.AddModeError(string.empty,"Subject not found");
}
//to do : Reload dropdown data and return the view

The ViewData item that has the key "my ID" is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'

Trying to edit a foreign key value in a table. In the edit of my controller I create a viewbag item as a selectlist of the foreign table, with the selected value from the table I want to edit. I am able to populate the dropdownlistfor the correct field, and the correct value is selected. I added the id's to the edit(BIND"...") values, but when I pass the values, the modelstate is invalid.
The simplified Model:
public class NOEDetail
{
[Key]
public int noeKey { get; set; }
[Required]
public virtual Patient patientID { get; set; }
[Display(Name="Attending Physician")]
public virtual Physician attendingPhysician { get; set; }
[Display(Name="Certifying Physician")]
public virtual Physician certifyingPhysician { get; set; }
//public IEnumerable<Physician> attendingEnum { get; set; }
//public IEnumerable<Physician> certifyingEnum { get; set; }
[StringLength(60)]
[Display(Name = "Last Name")]
public string lastName { get; set; }
[StringLength(35)]
[Display(Name = "First Name")]
public string firstName { get; set; }
[StringLength(25)]
public string middleName { get; set; }
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
[Display(Name = "Date Of Birth")]
public DateTime dob { get; set; }
[Display(Name = "Gender")]
public char? gender { get; set; }
[Display(Name = "Address 1")]
[StringLength(50)]
public string addr1 { get; set; }
[Display(Name = "Address 2")]
[StringLength(50)]
public string addr2 { get; set; }
[StringLength(50)]
[Display(Name = "City")]
public string city { get; set; }
[StringLength(2)]
[Display(Name = "State")]
public string state { get; set; }
[StringLength(9)]
[Display(Name = "Zip")]
public string zip { get; set; }
}
The simplified controller:
public class NOEDetailsController : Controller
{
private revDemo db = new revDemo();
// GET: NOEDetails/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
NOEDetail nOEDetail = db.NOEDetails.Find(id);
if (nOEDetail == null)
{
return HttpNotFound();
}
ViewBag.attendingPhysicianSelectList = new SelectList(db.Physician, "physicianID", "Fullname", nOEDetail.attendingPhysician.physicianID);
ViewBag.certifyingPhysicianSelectList = new SelectList(db.Physician, "physicianID", "Fullname", nOEDetail.certifyingPhysician.physicianID);
return View(nOEDetail);
}[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "noeKey,lastName,firstName,middleName,addr1,addr2,city,state,zip attendingPhysician,certifyingPhysician")] NOEDetail nOEDetail)
{//^^ here I added the attendingPhysician, and certifyingPhysician code BY HAND to get rid of the first error, but then the model was incorrect.
//ViewBag.attendingPhysicianSelectList = new SelectList(db.Physician, "physicianID", "Fullname", nOEDetail.attendingPhysician.physicianID);
//ViewBag.certifyingPhysicianSelectList = new SelectList(db.Physician, "physicianID", "Fullname", nOEDetail.certifyingPhysician.physicianID);
if (ModelState.IsValid)
{
db.Entry(nOEDetail).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(nOEDetail);
}
The View Item:
#Html.DropDownListFor(m => m.attendingPhysician.physicianID, ViewBag.attendingPhysicianSelectList as SelectList,null, new { #class = "form-control"})
The issue is when I submit the data. The data is retrieved correctly but is being sent back to the controller as a selectlistitem instead of the value tied to the item, which is what I want. Help, please?

How to validate IList foreign key? Entity Framework

Please help solve my problem. I want get message if textbox TagsSites is empty.
My models:
Site:
public int Id { get; set; }
[Required]
public string UserId { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Description { get; set; }
[Required]
public string TypeMenuId { get; set; }
public virtual IList<Page> Pages { get; set; }
[Required]
public virtual IList<TagSite> TagsSites { get; set; }
public virtual TypeMenu TypeMenu { get; set; }
public virtual ApplicationUser User { get; set; }
Tag:
public int Id { get; set; }
public string Name { get; set; }
public virtual IList<TagSite> TagsSites { get; set; }
TagSite:
public int Id { get; set; }
public int SiteId { get; set; }
public int TagId { get; set; }
public virtual Site Site { get; set; }
public virtual Tag Tag { get; set; }
I now get this message for all empty inputs.
How to get message "The TagsSites field is required." ?
Thanks.
What you may want here is the MinLengthAttribute. Implementation looks something like this.
[Required]
[MinLength (1)]
public virtual IList <TagSite> TagSites { get; set; }
You should create a view model for your view with a property for a comma separated tag names and mark it with the Required attribute.
public class CreateSiteVm
{
[Required]
public string Name { set;get;}
[Required]
public string Description { set;get;}
[Required]
public string Tags { set;get;}
[Required]
public int TypeMenuId { set;get;}
public List<SelectListItem> TypeMenus { set;get;}
}
and in your GET action
public ActionResult Create()
{
var vm = new CreateSiteVm();
vm.TypeMenus = dbContext.TypeMenus.Select(x=> new SelectListItem {
Value=x.Id.ToString(),
Text=x.Name}).ToList();
return View(vm);
}
and in your view,
#model CreateSiteVm
#using(Html.BeginForm())
{
<p>#Html.ValidationSummary(false)</p>
<label>Name</label>
#Html.TextBoxFor(f=>f.Name)
<label>Descsription</label>
#Html.TextBoxFor(f=>f.Descsription)
<label>Tags</label>
#Html.TextBoxFor(f=>f.Tags)
<input type="submit" />
}
and in your HttpPost action method, create an object of your entity and set the values from view model object which is your method parameter. You can use Split method to split the comma separated string.
[HttpPost]
public ActionResult Create(CreateSiteVm model)
{
if(ModelState.IsValid)
{
var e=new Site { Name = model.Name, Description = model.Description};
e.TypeMenuId = model.TypeMenuId;
var arr = model.Tags.Split(',');
foreach (var s in arr)
{
e.Tags.Add(new Tag { Name = s});
}
dbContext.Sites.Add(e);
dbContext.SaveChanges();
return RedirectToAction("Index");
}
//to do : Load the dropdown again same as GET
return View(model);
}

Update ViewModel with one-to-one relationship by code first

I have 2 table with one-to-one relationship:
public class PersonCall
{
public PersonCall()
{
Destination = new Destination();
}
[Key, ForeignKey("Destination")]
public int DestinationId { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
public string Job { get; set; }
public virtual Destination Destination { get; set; }
}
public partial class Destination
{
public int DestinationId { get; set; }
public int? ActivityId { get; set; }
[StringLength(50)]
public string ActivityTextPersian { get; set; }
public int Number { get; set; }
public virtual Activity Activity { get; set; }
public virtual PersonCall PersonCall { get; set; }
}
and a PersonCallViewModel like this:
public class PersonCallViewModel
{
public int DestinationId { get; set; }
[Required(ErrorMessage = "پر کردن این فیلد الزامی است")]
[Display(Name = "نام")]
public string FirstName { get; set; }
[Required(ErrorMessage = "پر کردن این فیلد الزامی است")]
[Display(Name = "نام خانوادگی")]
public string LastName { get; set; }
[Required(ErrorMessage = "پر کردن این فیلد الزامی است")]
[Display(Name = "سمت")]
public string Job { get; set; }
[Required(ErrorMessage = "پر کردن این فیلد الزامی است")]
[Display(Name = "شماره پیجر")]
public int Pager { get; set; }
}
and it's PersonUpdate action in PersonCallController:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult PersonUpdate([DataSourceRequest] DataSourceRequest request, PersonCallViewModel personCall)
{
if (personCall != null && ModelState.IsValid)
{
personCallService.Update(personCall);
}
var updateEntity = Json(new[] { personCall }.ToDataSourceResult(request, ModelState)); ;
return updateEntity;
}
My problem is when update Pager property in PersonCallViewModel, database not updated it!
in fact, my grid is updated but when I refresh page or see my table rows in database my value rollback to previous value.
here is my code:
public void Update(PersonCallViewModel personCall)
{
var entity = new PersonCall();
entity.DestinationId = personCall.DestinationId;
entity.Destination.DestinationId = personCall.DestinationId;
entity.FirstName = personCall.FirstName;
entity.LastName = personCall.LastName;
entity.Job = personCall.Job;
entity.Destination.Number = personCall.Pager;
entities.PersonCall.Attach(entity);
entities.Entry(entity).State = EntityState.Modified;
entities.SaveChanges();
}
do you help me?
I solved this problem! thanks of #Henk Holterman for his help!
I create a new object of Destination in Update method and apply changes to that as below:
public void Update(PersonCallViewModel personCall)
{
var entity = new PersonCall();
var entity2 = new Destination();
entity.DestinationId = personCall.DestinationId;
entity.Destination.DestinationId = personCall.DestinationId;
entity.FirstName = personCall.FirstName;
entity.LastName = personCall.LastName;
entity.Job = personCall.Job;
entities.PersonCall.Attach(entity);
var equalDestination = entities.Destination.Where(pd => pd.DestinationId == entity.DestinationId);
foreach (var item in equalDestination)
{
item.Number = personCall.Pager;
}
entity2 = equalDestination.FirstOrDefault();
entities.Destination.Attach(entity2);
entities.Entry(entity).State = EntityState.Modified;
entities.Entry(entity2).State = EntityState.Modified;
entities.SaveChanges();
}

ViewModel save selected value from dropdownlist

I have a dropdownlist - difficult. This is a dropdonwlinst where the user can select a value(easy, hard) but the value is not saved to the database, if I select a value. The strange thing I also have Country list, and that value is saved to the database.And If I put the values by hand in the database - for difficult the values are shown in the view
ModelVIew:
public RouteViewModel()
{
Countries = new List<SelectListItem>();
DifficultGrades = new List<SelectListItem>();
}
public int Id { get; set; }
[Required(ErrorMessage = "You need to give it a name")]
public string Name { get; set; }
public int SelectedValue { get; set; }
public int SelectedId { get; set; }
public IEnumerable<SelectListItem> Countries { get; set; }
public IEnumerable<SelectListItem> DifficultGrades { get; set; }
}
public class Difficult
{
[Key]
public int DifficultId { get; set; }
public string DifficultName { get; set; }
public virtual ICollection<Route> Routes { get; set; }
}
public class Route
{
[Key]
public int routeID { get; set; }
public string Name { get; set; }
public int? UserProfileID { get; set; }
public int? CountryID { get; set; }
public int? DifficultGradeID { get; set; }
public virtual UserProfile userProfile { get; set; }
public virtual Country country { get; set; }
public virtual Difficult difficult { get; set; }
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(RouteViewModel routeViewModel )
{
try
{
if (ModelState.IsValid)
{
var route = new Route();
UpdateRoute(route, routeViewModel);
db.Routes.Add(route);
db.SaveChangesAsync();
return RedirectToAction("Index");
}
}
catch (RetryLimitExceededException /* dex */)
{
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
ViewBag.Id = new SelectList(db.countries, "Id", "country_name", routeViewModel.Id);
ViewBag.DifficultId = new SelectList(db.difficulties, "DifficultId", "DifficultName", routeViewModel.Id);
return View(new RouteViewModel());
}
and the update method:
public void UpdateRoute(Route route, RouteViewModel routeViewModel )
{
route.routeID = routeViewModel.Id;
route.Name = routeViewModel.Name;
route.CountryID = routeViewModel.Id;
route.DifficultGradeID = routeViewModel.Id;
// climb.country.country_name = ModelViewClimb.Name;
}
Thank you

Categories