I have a view inside Admin area and I want to populate it with the following codes but
when I run the program my view shows nothing except empty controls. It returns string without any problems but have trouble with viewmodels
My viewmodel is as follow:
public class AddQuestionsViewModel
{
[Required]
[MinLength(20)]
public string Question { get; set; }
[Required]
[MinLength(50)]
public string Answer { get; set; }
public string Category { get; set; }
public int CategoryId { get; set; }
public SelectList Categories { get; set; }
public DateTime DateTime { get; set; }
public bool IsDisplayed { get; set; }
public int UserId { get; set; }
}
My view:
#model MosahebeClient.Areas.Admin.Models.AddQuestionsViewModel
#{
ViewData["Title"] = "Create";
Layout = "~/Areas/Admin/Views/Shared/_AdminLayout.cshtml";
}
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Question" class="control-label"></label>
<input asp-for="Question" class="form-control" />
<span asp-validation-for="Question" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Answer" class="control-label"></label>
<input asp-for="Answer" class="form-control" />
<span asp-validation-for="Answer" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Category" class="control-label"></label>
<input asp-for="Category" class="form-control" />
<span asp-validation-for="Category" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CategoryId" class="control-label"></label>
<input asp-for="CategoryId" class="form-control" />
<span asp-validation-for="CategoryId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="DateTime" class="control-label"></label>
<input asp-for="DateTime" class="form-control" />
<span asp-validation-for="DateTime" class="text-danger"></span>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="IsDisplayed" /> #Html.DisplayNameFor(model => model.IsDisplayed)
</label>
</div>
<div class="form-group">
<label asp-for="UserId" class="control-label"></label>
<input asp-for="UserId" class="form-control" />
<span asp-validation-for="UserId" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
My Controller:
[Area("Admin")]
public ActionResult Create()
{
AddQuestionsViewModel model = new AddQuestionsViewModel();
model.Categories = new SelectList(_categoryRepository.GetAll(), "Id", "Name");
return View(model);
}
Do you want to add a drop-down list to your view? If so, you can add the following code in your view.
//...
<select asp-items="#Model.Categories">
<option>Please select a option</option>
</select>
//...
Related
I try make a library Sistem where in category to book has a relation many to many i need put in my book edit view a partial view frow the entity, could someone help-me?
my edit view:
#model MVC_Library.Models.Book
#{
ViewData["Title"] = "Edit";
BookCategory teste = ViewBag.testeview;
}
<h1>Edit</h1>
<h4>Book</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="BookId" />
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Author" class="control-label"></label>
<input asp-for="Author" class="form-control" />
<span asp-validation-for="Author" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PublishDate" class="control-label"></label>
<input asp-for="PublishDate" class="form-control" />
<span asp-validation-for="PublishDate" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="BasePrice" class="control-label"></label>
<input asp-for="BasePrice" class="form-control" />
<span asp-validation-for="BasePrice" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Quantity" class="control-label"></label>
<input asp-for="Quantity" class="form-control" />
<span asp-validation-for="Quantity" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PublishingCompanyId" class="control-label"></label>
<select asp-for="PublishingCompanyId" class="form-control" asp-items="ViewBag.PublishingCompanyId"></select>
<span asp-validation-for="PublishingCompanyId" class="text-danger"></span>
</div>
<div>
#Html.Partial("_EditBookCategory", teste)
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
my partial view that work (but in this way just pre-select one category item)
#model MVC_Library.Models.BookCategory
<div class="row">
<div class="col-md-12">
<label asp-for="CategoryId" class="control-label"></label>
<select multiple asp-for="CategoryId" class="form-control" name = "BookCategory[]" asp-items="ViewBag.SelectedCategory"></select>
</div>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
and my controller edit part
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var book = await _context.Books.FindAsync(id);
if (book == null)
{
return NotFound();
}
List<BookCategory> bookCategory = _context.BookCategories.Where(e => e.BookId == id).ToList();
ViewData["PublishingCompanyId"] = new SelectList(_context.PublishingCompanies, "PublishingCompanyId", "PublishingCompanyName", book.PublishingCompanyId);
//this is what i try for try return mutiple category select (don't work with this viewbag)
/* ViewBag.SelectedCategory = new MultiSelectList(_context.Categories.ToList(), "CategoryId", "CategoryName", bookCategory); */
//this viewbag return only one category selected but work
ViewBag.testeview = bookCategory.First();
return View(book);
}
Just once selected (the first), but a want to return all. Need help if this could possible.
If you want to display all the related categories selected:
Be sure asp-for="CategoryId" here CategoryId should be type of int[] or string[]. Or just remove asp-for tag helper, because you have added name="BookCategory[]" here, it will override asp-for generated name attribute. When you form submit, your action always need contain a parameter named BookCategory[], no matter you add asp-for or not.
Besides BookCategory[] is not a correct name with no index in array, it should be BookCategory or any other name and the parameter name in action should be type of int[] or string[]. Guessing you may want to match the selected value to List model BookCategory's CategoryId. It is not acceptable for multiple select.
Be sure the last parameter in MultiSelectList should be int[] or string[]. From your code, the dataValueField in MultiSelectList matches CategoryId property, so your last parameter should be something like bookCategory.Select(a=>a.CategoryId).ToList().
ViewBag.SelectedCategory = new MultiSelectList(_context.Categories.ToList(), "CategoryId", "CategoryName",
bookCategory.Select(a=>a.CategoryId).ToList());
No need use ViewBag.testeview, just change like below:
#Html.Partial("_EditBookCategory", new BookCategory())
Whole working demo should be like:
Model:
public class Book
{
public int BookId { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public DateTime PublishDate { get; set; }
public int BasePrice { get; set; }
public int Quantity { get; set; }
public int PublishingCompanyId { get; set; }
public List<BookCategory> BookCategory { get; set; }
}
public class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public List<BookCategory> BookCategory { get; set; }
}
public class BookCategory
{
public int CategoryId { get; set; }
public int BookId { get; set; }
public Category Category { get; set; }
public Book Book { get; set; }
}
View:
#model Book
#{
ViewData["Title"] = "Edit";
}
<h1>Edit</h1>
<h4>Book</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="BookId" />
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Author" class="control-label"></label>
<input asp-for="Author" class="form-control" />
<span asp-validation-for="Author" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PublishDate" class="control-label"></label>
<input asp-for="PublishDate" class="form-control" />
<span asp-validation-for="PublishDate" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="BasePrice" class="control-label"></label>
<input asp-for="BasePrice" class="form-control" />
<span asp-validation-for="BasePrice" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Quantity" class="control-label"></label>
<input asp-for="Quantity" class="form-control" />
<span asp-validation-for="Quantity" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PublishingCompanyId" class="control-label"></label>
<select asp-for="PublishingCompanyId" class="form-control" asp-items="ViewBag.PublishingCompanyId"></select>
<span asp-validation-for="PublishingCompanyId" class="text-danger"></span>
</div>
<div>
//change here....
#Html.Partial("_EditBookCategory", new BookCategory())
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Partial View:
#model BookCategory
<div class="row">
<div class="col-md-12">
<label asp-for="CategoryId" class="control-label"></label>
<select multiple class="form-control" name="CategoryId" asp-items="ViewBag.SelectedCategory"></select>
</div>
</div>
Controller:
Note: I just hard-coded the data due to easy testing, it is the same with your get data from database. You just need change like what my comment said, other code is no need change like what I did.
public IActionResult Edit(int? id)
{
var book = new Book()
{
BookId = 1,
PublishDate = DateTime.Now,
Author = "a1",
BasePrice = 34,
PublishingCompanyId = 1,
Quantity = 23,
Title = "aa"
};
List<BookCategory> bookCategory = new List<BookCategory>()
{
new BookCategory(){BookId=1,CategoryId=1},
new BookCategory(){BookId=2,CategoryId=1},
new BookCategory(){BookId=2,CategoryId=3}
};
ViewData["PublishingCompanyId"] = new List<SelectListItem>() {
new SelectListItem() { Value = "1", Text = "Elementos1" },
new SelectListItem() { Value = "2", Text = "Elementos2" },
new SelectListItem() { Value = "3", Text = "Elementos3" }
};
var c = new List<Category>()
{
new Category(){CategoryId=1,Name="aa"},
new Category(){CategoryId=2,Name="bb"},
new Category(){CategoryId=3,Name="cc"}
};
//change here....
ViewBag.SelectedCategory = new MultiSelectList(c, "CategoryId", "Name", bookCategory.Select(a=>a.CategoryId).ToList());
//ViewBag.testeview = bookCategory.First();
return View(book);
}
[HttpPost]
public IActionResult Edit(int? id,Book book, int[] CategoryId)
{
//do your stuff......
return View();
}
Result:
For how to choose multiple option, you just need press Ctrl key meanwhile click the option.
I am trying to implement a feature to let super admins modify the data of regular admin account, but I ran into an error of "User security stamp cannot be null." But in the database, there IS the SecurityStamp field filled.
Here are my Admin class which is inherited from the customized ApplicationUser class with no extra fields yet.
public abstract class ApplicationUser : IdentityUser<int>
{
//STORED FIELDS
[Required, StringLength(50, MinimumLength = 3), PersonalData]
public string FirstName { get; set; }
[Required, StringLength(50, MinimumLength = 3), PersonalData]
public string LastName { get; set; }
[Required, StringLength(6, MinimumLength = 6), PersonalData]
public string NeptunCode { get; set; }
public int UsernameChangeLimit { get; set; } = 10;
[PersonalData]
public byte[] ProfilePicture { get; set; }
//CALCULATED FIELDS
public string FullName => FirstName + " " + LastName;
}
public class Admin : ApplicationUser
{
}
And here are my AdminController and AdminService methods.
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Modify(int? id, Admin admin)
{
if (id != admin.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
await _adminService.UpdateAdminAsync(admin);
return RedirectToAction(nameof(Index));
}
return View(admin);
}
public async Task<bool> UpdateAdminAsync(Admin admin)
{
await _userManager.UpdateAsync(admin);
return await _context.SaveChangesAsync() == 1;
}
And finally, Modify.cshtml
<form asp-action="Modify">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Id" />
<div class="form-group text-center">
<label asp-for="FirstName" class="control-label"></label>
<input asp-for="FirstName" class="form-control text-center" />
<span asp-validation-for="FirstName" class="text-danger"></span>
</div>
<div class="form-group text-center">
<label asp-for="LastName" class="control-label"></label>
<input asp-for="LastName" class="form-control text-center" />
<span asp-validation-for="LastName" class="text-danger"></span>
</div>
<div class="form-group text-center">
<label asp-for="UserName" class="control-label"></label>
<input asp-for="UserName" class="form-control text-center" />
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
<div class="form-group text-center">
<label asp-for="Email" class="control-label"></label>
<input asp-for="Email" class="form-control text-center" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
<div class="form-group form-check text-center">
<label class="form-check-label">
<input class="form-check-input" asp-for="EmailConfirmed" /> #Html.DisplayNameFor(model => model.EmailConfirmed)
</label>
</div>
<div class="form-group text-center">
<label asp-for="NeptunCode" class="control-label"></label>
<input asp-for="NeptunCode" class="form-control text-center" />
<span asp-validation-for="NeptunCode" class="text-danger"></span>
</div>
<div class="form-group text-center">
<label asp-for="PhoneNumber" class="control-label"></label>
<input asp-for="PhoneNumber" class="form-control text-center" />
<span asp-validation-for="PhoneNumber" class="text-danger"></span>
</div>
<div class="form-group form-check text-center">
<label class="form-check-label">
<input class="form-check-input" asp-for="PhoneNumberConfirmed" /> #Html.DisplayNameFor(model => model.PhoneNumberConfirmed)
</label>
</div>
<div class="form-group text-center">
<input type="submit" value="Save" class="btn btn-primary btn-block" />
<a asp-action="Index" class="btn btn-outline-primary btn-block">Back to List</a>
</div>
</form>
Thank you for your help!
SecurityStamp is a requierd field . You will have to create a hidden input for Model.SecurityStamp somewhere inside a view form
<input type="hidden" asp-for="SecurityStamp" value="#Model.SecurityStamp" />
public class Product
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string SKU { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public bool Status { get; set; }
public bool IsMenuItem { get; set; }
public int Count { get; set; }
public int? CategoryId { get; set; }
public Category Category { get; set; }
}
public class Category
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
I want to add 'CategoryId' DropDown List instead of <here> tag
#model OnlineShopArmenia.Models.Product
#{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Product</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="SKU" class="control-label"></label>
<input asp-for="SKU" class="form-control" />
<span asp-validation-for="SKU" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Description" class="control-label"></label>
<input asp-for="Description" class="form-control" />
<span asp-validation-for="Description" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Price" class="control-label"></label>
<input asp-for="Price" class="form-control" />
<span asp-validation-for="Price" class="text-danger"></span>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="Status" /> #Html.DisplayNameFor(model => model.Status)
</label>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="IsMenuItem" /> #Html.DisplayNameFor(model => model.IsMenuItem)
</label>
</div>
<div class="form-group">
<label asp-for="Count" class="control-label"></label>
<input asp-for="Count" class="form-control" />
<span asp-validation-for="Count" class="text-danger"></span>
</div>
<here>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
you can use this code in your controller:
ViewBag.Categories = new SelectList(List of categories for show in view, "Id", "Name");
if you have categories in your data base you can make a query for get list of categories or you can make a list of categories with Id and Name then pass the list into first parameter of SelectList.
in your View:
<div class="form-group">
<label>Categories :</label>
<select name="CategoryId" asp-for="CategoryId" class="formcontrol" asp-items="ViewBag.Categories">
<option value="">Please choose user category:</option>
</select>
<span asp-validation-for="CategoryId" class="text-danger"></span>
</div>
or generate it by tag helper:
#Html.DropDownListFor(model => Category ,ViewBag.Categories as SelectList, new { #class = "form-group"} )
I struggle with issue to pass value for double property. As property regards coordinates (Latitude, Longitude) their format will be ###.######. On my PC default numeric format is ### ###,##
My input field pass only values ###,###. If put something different like:
1234,444 then I receive message "The field Latitude must be a number." and in code property got value 0
130.653221 =>the same, property receive 0 and I got message "The value '130.653221' is not valid for Latitude."
12,1234 then client validator won't pass me because "The field Latitude must be a number."
I tried to put regular expression in ViewModel e.g. [RegularExpression(#"^\d+.\d{0,6}$")] but unsuccessful.
Is there any way to change format of value to ###.######?
Below you can find my code:
ViewModel
public class ShopLocationViewModel
{
public int Id { get; set; }
public string Header { get; set; }
public string FirstText { get; set; }
public string SecondText { get; set; }
public string ThirdText { get; set; }
public string LinkText { get; set; }
public string Link { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public int Priority { get; set; }
}
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind("Header,FirstText,SecondText,ThirdText,LinkText,Link,Latitude,Longitude,Priority,Id")] ShopLocationViewModel shopLocation)
{
if (ModelState.IsValid)
{
var shopLocationDto = _viewModelMapper.Map(shopLocation);
_dataManger.AddNewShopLocation(shopLocationDto);
return RedirectToAction(nameof(Index));
}
return View(shopLocation);
}
View:
#model ShopLocationViewModel
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Header" class="control-label"></label>
<input asp-for="Header" class="form-control" />
<span asp-validation-for="Header" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="FirstText" class="control-label"></label>
<input asp-for="FirstText" class="form-control" />
<span asp-validation-for="FirstText" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="SecondText" class="control-label"></label>
<input asp-for="SecondText" class="form-control" />
<span asp-validation-for="SecondText" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ThirdText" class="control-label"></label>
<input asp-for="ThirdText" class="form-control" />
<span asp-validation-for="ThirdText" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="LinkText" class="control-label"></label>
<input asp-for="LinkText" class="form-control" />
<span asp-validation-for="LinkText" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Link" class="control-label"></label>
<input asp-for="Link" class="form-control" />
<span asp-validation-for="Link" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Latitude" class="control-label"></label>
<input asp-for="Latitude" class="form-control" />
<span asp-validation-for="Latitude" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Longitude" class="control-label"></label>
<input asp-for="Longitude" class="form-control" />
<span asp-validation-for="Longitude" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Priority" class="control-label"></label>
<input asp-for="Priority" class="form-control" />
<span asp-validation-for="Priority" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}}
All CRUD operations are working except updating/editing. I am using Pomelo since I am using Mysql. For the issue am facing, am using the same create form to edit the data but it throws an exception when I try editing.
This is the exception:
fail: Microsoft.EntityFrameworkCore.Update[10000]
An exception occurred in the database while saving changes for context type 'ICFERApp.Data.ApplicationDbContext'.
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
MySql.Data.MySqlClient.MySqlException: Duplicate entry '3' for key 'IX_Education_StudentId'
MySql.Data.MySqlClient.MySqlException: Duplicate entry '3' for key 'IX_Education_StudentId'
at MySqlConnector.Core.ResultSet.ReadResultSetHeaderAsync(IOBehavior
ioBehavior) in C:\projects\mysqlconnector\src\MySqlConnector\Core\ResultSet.cs:line 43
--- End of inner exception stack trace ---
at MySql.Data.MySqlClient.MySqlDataReader.ActivateResultSet(ResultSet
resultSet) in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 81
at MySql.Data.MySqlClient.MySqlDataReader.ReadFirstResultSetAsync(IOBehavior
ioBehavior) in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 307
These are my model classes:
public class Student
{
[Key]
public long Id { get; set; }
[Display(Name="First Name")]
public string FirstName { get; set; }
[Display(Name="Middle Name")]
public string MiddleName { get; set; }
[Display(Name="Last Name")]
public string LastName { get; set; }
[Display(Name="Nationality")]
public string Nationality { get; set; }
[Display(Name="Gender")]
public string Gender { get; set; }
[Display(Name="Religion")]
public string Religion { get; set; }
[Display(Name="Medical Condition")]
public string MedicalCondition { get; set; }
[Display(Name="Deceased")]
public string Deceased { get; set; }
[Display(Name="Home Address")]
public string HomeAddress { get; set; }
[Display(Name="Country Of Residence")]
public string CountryOfResidence { get; set; }
[Display(Name="City")]
public string City { get; set; }
[Display(Name="Date Of Birth")]
public DateTime DateOfBirth { get; set; }
public int Age { get; set; }
public virtual Parents Parents { get; set; }
public virtual Education Education { get; set; }
}
public class Parents
{
public long Id { get; set; }
[Display(Name="Religion Of Deceased Father")]
public string ReligionOfDeceasedFather { get; set; }
[Display(Name="Religion Of Deceased Mother")]
public string ReligionOfDeceasedMother { get; set; }
[Display(Name="Date Of Demise Father")]
[DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}")]
public DateTime DateOfDemiseOfFather { get; set; }
[Display(Name="Date Of Demise Mother")]
[DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}")]
public DateTime DateOfDemiseOfMother { get; set; }
[Display(Name="Names of Mother")]
public string NamesOfMother { get; set; }
[Display(Name="Names of Father")]
public string NamesOfFather { get; set; }
[Display(Name="Religion of Mother")]
public string ReligionOfMother { get; set; }
[Display(Name="Marital Status of Mother")]
public string MaritalStatusOfMother { get; set; }
[Display(Name="Occupation of Mother")]
public string OccupationOfMother { get; set; }
[Display(Name="Monthly Income")]
public double MonthlyIncome { get; set; }
public virtual Student Student { get; set; }
public long? StudentId { get; set; }
}
public class Education
{
public long Id { get; set; }
[Display(Name="Education Level")]
public string EducationLevel { get; set; }
[Display(Name="School")]
public string School { get; set; }
[Display(Name="Address of School")]
public string AddressOfSchool { get; set; }
[Display(Name="Head Teacher")]
public string HeadTeacher { get; set; }
[Display(Name="Telephone")]
public string Telephone { get; set; }
public virtual Student Student { get; set; }
public long? StudentId { get; set; }
}
My question would be why can't I be able to update automatically with the Entity Framework Core?
These are the methods responsible for editing in my Controller class :
[HttpPost]
public IActionResult New(Student student, string IsEditMode)
{
if (!ModelState.IsValid)
{
ViewBag.IsEditMode = IsEditMode;
return View(student);
}
try
{
if (IsEditMode.Equals("false"))
{
_studentRepository.Create(student);
}
else
{
_studentRepository.Edit(student);
}
return RedirectToAction(nameof(Index));
}
catch (Exception e)
{
return RedirectToAction(nameof(Index));
}
}
public IActionResult Edit(int id)
{
try
{
ViewBag.IsEditMode = "true";
var student = _studentRepository.GetSingleStudent(id);
return View("New", student);
}
catch (Exception ex)
{
return Content("Could not find Pet");
}
}
Then, in my Repository class, this is the Edit method:
public void Edit(Student student)
{
_context.Students.Update(student);
_context.SaveChanges();
}
I will be very grateful with help regarding this blocker. Thanks.
EDIT
This is my form which handles both Creating and Editing.
#model Student
<form asp-action="New" method="Post" asp-controller="Student">
<div asp-validation-summary="All"></div>
<input asp-for="Id" type="hidden"/>
<input name="IsEditMode" id="IsEditMode" value="#ViewBag.IsEditMode" type="hidden"/>
<div class="form-row">
<div class="col">
<label asp-for="FirstName"></label>
<input asp-for="FirstName" class="form-control"/>
<span asp-validation-for="FirstName" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="MiddleName"></label>
<input asp-for="MiddleName" class="form-control"/>
<span asp-validation-for="MiddleName" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="LastName"></label>
<input asp-for="LastName" class="form-control"/>
<span asp-validation-for="LastName" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="Nationality"></label>
<input asp-for="Nationality" class="form-control"/>
<span asp-validation-for="Nationality" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="Gender"></label>
<input asp-for="Gender" class="form-control"/>
<span asp-validation-for="Gender" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="Religion"></label>
<input asp-for="Religion" class="form-control"/>
<span asp-validation-for="Religion" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="MedicalCondition"></label>
<input asp-for="MedicalCondition" class="form-control"/>
<span asp-validation-for="MedicalCondition" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="Deceased"></label>
<input asp-for="Deceased" class="form-control"/>
<span asp-validation-for="Deceased" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="HomeAddress"></label>
<input asp-for="HomeAddress" class="form-control"/>
<span asp-validation-for="HomeAddress" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="CountryOfResidence"></label>
<input asp-for="CountryOfResidence" class="form-control"/>
<span asp-validation-for="CountryOfResidence" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="City"></label>
<input asp-for="City" class="form-control"/>
<span asp-validation-for="City" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="DateOfBirth"></label>
<input asp-for="DateOfBirth" class="form-control"/>
<span asp-validation-for="DateOfBirth" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="Parents.ReligionOfDeceasedFather"></label>
<input asp-for="Parents.ReligionOfDeceasedFather" class="form-control"/>
<span asp-validation-for="Parents.ReligionOfDeceasedFather" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="Parents.ReligionOfDeceasedMother"></label>
<input asp-for="Parents.ReligionOfDeceasedMother" class="form-control"/>
<span asp-validation-for="Parents.ReligionOfDeceasedMother" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="Parents.DateOfDemiseOfFather"></label>
<input asp-for="Parents.DateOfDemiseOfFather" class="form-control"/>
<span asp-validation-for="Parents.DateOfDemiseOfFather" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="Parents.DateOfDemiseOfMother"></label>
<input asp-for="Parents.DateOfDemiseOfMother" class="form-control"/>
<span asp-validation-for="Parents.DateOfDemiseOfMother" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="Parents.NamesOfMother"></label>
<input asp-for="Parents.NamesOfMother" class="form-control"/>
<span asp-validation-for="Parents.NamesOfMother" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="Parents.NamesOfFather"></label>
<input asp-for="Parents.NamesOfFather" class="form-control"/>
<span asp-validation-for="Parents.NamesOfFather" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="Parents.ReligionOfMother"></label>
<input asp-for="Parents.ReligionOfMother" class="form-control"/>
<span asp-validation-for="Parents.ReligionOfMother" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="Parents.MaritalStatusOfMother"></label>
<input asp-for="Parents.MaritalStatusOfMother" class="form-control"/>
<span asp-validation-for="Parents.MaritalStatusOfMother" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="Parents.OccupationOfMother"></label>
<input asp-for="Parents.OccupationOfMother" class="form-control"/>
<span asp-validation-for="Parents.OccupationOfMother" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="Parents.MonthlyIncome"></label>
<input asp-for="Parents.MonthlyIncome" class="form-control"/>
<span asp-validation-for="Parents.MonthlyIncome" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="Guardian.FirstName"></label>
<input asp-for="Guardian.FirstName" class="form-control"/>
<span asp-validation-for="Guardian.FirstName" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="Guardian.MiddleName"></label>
<input asp-for="Guardian.MiddleName" class="form-control"/>
<span asp-validation-for="Guardian.MiddleName" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="Guardian.LastName"></label>
<input asp-for="Guardian.LastName" class="form-control"/>
<span asp-validation-for="LastName" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="Guardian.RelationshipToOrphan"></label>
<input asp-for="Guardian.RelationshipToOrphan" class="form-control"/>
<span asp-validation-for="Guardian.RelationshipToOrphan" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="Guardian.Occupation"></label>
<input asp-for="Guardian.Occupation" class="form-control"/>
<span asp-validation-for="Guardian.Occupation" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="Guardian.MonthlyIncome"></label>
<input asp-for="Guardian.MonthlyIncome" class="form-control"/>
<span asp-validation-for="Guardian.MonthlyIncome" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="Guardian.EmployersName"></label>
<input asp-for="Guardian.EmployersName" class="form-control"/>
<span asp-validation-for="Guardian.EmployersName" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="Guardian.WorkAddress"></label>
<input asp-for="Guardian.WorkAddress" class="form-control"/>
<span asp-validation-for="Guardian.WorkAddress" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="Guardian.MobileNo"></label>
<input asp-for="Guardian.MobileNo" class="form-control"/>
<span asp-validation-for="Guardian.MobileNo" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="Guardian.PhysicalLocation"></label>
<input asp-for="Guardian.PhysicalLocation" class="form-control"/>
<span asp-validation-for="Guardian.PhysicalLocation" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="Guardian.Comments"></label>
<input asp-for="Guardian.Comments" class="form-control"/>
<span asp-validation-for="Guardian.Comments" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="Education.EducationLevel"></label>
<input asp-for="Education.EducationLevel" class="form-control"/>
<span asp-validation-for="Education.EducationLevel" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="Education.School"></label>
<input asp-for="Education.School" class="form-control"/>
<span asp-validation-for="Education.School" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="Education.AddressOfSchool"></label>
<input asp-for="Education.AddressOfSchool" class="form-control"/>
<span asp-validation-for="Education.AddressOfSchool" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="Education.HeadTeacher"></label>
<input asp-for="Education.HeadTeacher" class="form-control"/>
<span asp-validation-for="Education.HeadTeacher" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="Education.Telephone"></label>
<input asp-for="Education.Telephone" class="form-control"/>
<span asp-validation-for="Education.Telephone" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col">
<label asp-for="Siblings.NumberOfBrothers"></label>
<input asp-for="Siblings.NumberOfBrothers" class="form-control"/>
<span asp-validation-for="Siblings.NumberOfBrothers" class="text-danger"></span>
</div>
<div class="col">
<label asp-for="Siblings.NumberOfSisters"></label>
<input asp-for="Siblings.NumberOfSisters" class="form-control"/>
<span asp-validation-for="Siblings.NumberOfSisters" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<input asp-for="FirstName" type="submit" value="Save Student" class="btn btn-primary"/>
</div>
</form>
This is how you can update all the tables
public void Edit(Student student)
{
var existingStudent = _context.Students.FirstOrDefault(s => s.Id == student.Id);
if (existingStudent != null)
{
//do the update to the database
_context.Entry(existingStudent).CurrentValues.SetValues(student);
_context.Entry(existingStudent).State = System.Data.Entity.EntityState.Modified;
//then update the parent this way
//first get the particular parent for this student
var parent = _context.Parents.FirstOrDefault(m => m.StudentId == existingStudent.Id);
_context.Entry(parent).CurrentValues.SetValues(student.Parents);
_context.Entry(parent).State = System.Data.Entity.EntityState.Modified;
//do the same for Educations
}
_context.SaveChanges();
}