Testing a Website. While logged in as an admin, the user should be able to delete a Service. A Service could have sub categories known as "Service Options" and below that "Service Option Items". When an admin tries to permanently delete a service he/she receives the following server error.
Server Error
I have done some research and found out that the sub categories may need to be deleted first, and I believe the code reflects that.
Controller
//
// GET: /Service/Delete
[Authorize(Roles = "admin")]
public ActionResult Delete(int id)
{
Service serviceToDelete = db.Services.Where(s => s.ServiceId == id).Single();
return View(serviceToDelete);
}
//
// POST: /Service/Delete
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirm(int id)
{
var serviceToDelete = db.Services.Where(s => s.ServiceId == id).Single();
// remove the service option items
var serviceOptionItems = db.ServiceOptionItems.Where(soi => soi.ServiceOption.ServiceId == serviceToDelete.ServiceId);
foreach (var serviceOptionItem in serviceOptionItems)
{
db.ServiceOptionItems.Remove(serviceOptionItem);
}
// remove the service options
var serviceOptions = db.ServiceOptions.Where(so => so.ServiceId == serviceToDelete.ServiceId);
foreach (var serviceOption in serviceOptions)
{
db.ServiceOptions.Remove(serviceOption);
}
// remove the service
db.Services.Remove(serviceToDelete);
// save all changes
db.SaveChanges();
return RedirectToAction("Index", new { manage = "yes", mode = "all" });
}
View
#model YardLad.Models.Domain.Service
#{
ViewBag.Title = "Delete Service";
}
<script>
$(document).ready(function () {
var isConfirmed = false;
$("form").submit(function (e) {
if (!isConfirmed)
{
$("#dialog-confirm").dialog({
resizable: false,
height: 140,
modal: true,
buttons: {
"Yes": function () {
$(this).dialog("close");
isConfirmed = true;
$("#deleteService").submit();
},
Cancel: function () {
$(this).dialog("close");
}
}
});
e.preventDefault();
return false;
}
else
{
return true;
}
});
});
</script>
<h2>Delete</h2>
<h3>Are you sure you want to delete this service?</h3>
<div class="display-label">Service Category</div>
<div class="display-field">
#Html.DisplayFor(m => m.ServiceCategory.Name)
</div>
<div class="display-label">Name</div>
<div class="display-field">
#Html.DisplayFor(m => m.Name)
</div>
<div class="display-label">Description</div>
<div class="display-field">
#if (Model.Description == null)
{
#:No Description
}
else
{
#Html.DisplayFor(m => m.Description)
}
</div>
<div class="display-label">Base Price</div>
<div class="display-field">
#Html.DisplayFor(m => m.BasePrice)
</div>
<div class="display-label">Is Active</div>
<div class="display-field">
#Html.DisplayFor(m => m.IsActive)
</div>
#using (Html.BeginForm("Delete", "Service", null, FormMethod.Post, new { id = "deleteService" }))
{
<p>
<input type="submit" id="btnSubmit" value="Delete" />
</p>
}
<div>
#Html.ActionLink("Back", "Index", new { manage = "yes" })
</div>
<div id="dialog-confirm" title="Delete this service?" class="hidden">
<p>This service will be permanently deleted and cannot be recovered. Are you sure?</p>
</div>
Model
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using YardLad.Models.Domain;
namespace YardLad.Models.View
{
public class ServiceViewModel
{
[Display(Name = "Service Id")]
public int ServiceId { get; set; }
[Required(ErrorMessage = "please enter a name")]
public string Name { get; set; }
[UIHint("multilinetext")]
public string Description { get; set; }
[Display(Name = "Base Price")]
public decimal BasePrice { get; set; }
[Display(Name = "Service Category")]
[Required(ErrorMessage = "please select a category")]
public int ServiceCategoryId { get; set; }
[Display(Name = "Is Active?")]
public bool IsActive { get; set; }
[Display(Name = "Service options")]
public List<ServiceOption> ServiceOptions { get; set; }
}
public class RequestServiceViewModel
{
[Required(ErrorMessage = "please select a state")]
public int StateId { get; set; }
[Required(ErrorMessage = "please select a service area")]
public int ServiceAreaId { get; set; }
[Required(ErrorMessage = "please select a service")]
public int ServiceId { get; set; }
[Required(ErrorMessage = "please indicate the items selected")]
public string[] SelectedServiceOptionItemIds { get; set; }
[Required(ErrorMessage = "please indicate the contractors available for the request")]
public string[] AvailableContractorIds { get; set; }
public State SelectedState { get; set; }
public ServiceArea SelectedServiceArea { get; set; }
public Service SelectedService { get; set; }
public List<ServiceOption> SelectedServiceOptions { get; set; }
public List<ServiceOptionItem> SelectedServiceOptionItems { get; set; }
public List<Contractor> AvailableContractors { get; set; }
public int SelectedContractorId { get; set; }
public Contractor SelectedContractor { get; set; }
public int SelectedContractorServiceId { get; set; }
public ContractorService SelectedContractorService { get; set; }
public decimal SubTotal { get; set; }
public decimal Tax { get; set; }
public decimal SelectedContractorTaxRate { get; set; }
public decimal Total { get; set; }
public bool UserIsLoggedIn { get; set; }
public int UserAddressId { get; set; }
public Address UserAddress { get; set; }
public bool CreateCustomAddress { get; set; }
public Address CustomAddress { get; set; }
}
public class SelectContractorViewModel
{
public int ServiceAreaId { get; set; }
public ServiceArea SelectedServiceArea { get; set; }
public int ServiceId { get; set; }
public Service SelectedService { get; set; }
public List<ServiceOption> ServiceOptions { get; set; }
public List<ServiceOptionItem> ServiceOptionItems { get; set; }
public List<Contractor> AvailableContractors { get; set; }
public Contractor SelectedContractor { get; set; }
public int ContractorTypeId { get; set; }
public int ContractorServiceId { get; set; }
public ContractorService SelectedContractorService { get; set; }
public List<ContractorServiceOption> ContractorServiceOptions { get; set; }
public List<ContractorServiceOptionItem> ContractorServiceOptionItems { get; set; }
public decimal SubTotal { get; set; }
public decimal Tax { get; set; }
public decimal SelectedContractorTaxRate { get; set; }
public decimal Total { get; set; }
}
}
Image of DB relations:
edmx
Thank You for Reading
Your Service is related to ContractorService as well and there must be some child records in there to cause the error you posted. You'll need to remove all of those children like you did the other tables, but you also need to set the child entity to Deleted:
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirm(int id)
{
var serviceToDelete = db.Services.Where(s => s.ServiceId == id).Single();
// remove the service option items
var serviceOptionItems = db.ServiceOptionItems.Where(soi => soi.ServiceOption.ServiceId == serviceToDelete.ServiceId);
foreach (var serviceOptionItem in serviceOptionItems)
{
db.ServiceOptionItems.Remove(serviceOptionItem);
db.Entry(serviceOptionItem).State = EntityState.Deleted;
}
// remove the service options
var serviceOptions = db.ServiceOptions.Where(so => so.ServiceId == serviceToDelete.ServiceId);
foreach (var serviceOption in serviceOptions)
{
db.ServiceOptions.Remove(serviceOption);
db.Entry(serviceOption).State = EntityState.Deleted;
}
// remove the contractor services
var contractorServices = db.ContractorServices.Where(so => so.ServiceId == serviceToDelete.ServiceId);
foreach (var contractorService in contractorServices)
{
db.ContractorServices.Remove(contractorService);
db.Entry(contractorService).State = EntityState.Deleted;
}
// remove the service
db.Services.Remove(serviceToDelete);
// save all changes
db.SaveChanges();
return RedirectToAction("Index", new { manage = "yes", mode = "all" });
}
You have a foreign key constraint on the tables Service, ServiceOptions and ServiceOptions. Thus you will have to delete all the ServiceOptionsItems and ServiceOptions of that service before you can delete the service.
But if you have such requirement, I suggest you use ON DELETE CASCADE while adding the constraint. So that it will allow you to directly delete the service and will delete all the child ServiceOptions and ServiceOptionsItems automatically.
More Info: http://www.mysqltutorial.org/mysql-on-delete-cascade/
From the error message, it looks like you have the association between Service and something called ContractorService. Delete the related ContactorService entities first or remove or change its ServiceId value.
Related
I have this code inside my form:
<div class="form-group">
#Html.LabelFor(c => c.ClosingHourId)
#Html.DropDownListFor(c => c.ClosingHourId, new SelectList(Model.ClosingHours, "Id", "Time"), "Select time", new { #class = "form-control" })
#Html.ValidationMessageFor(c => c.ClosingHourId)
</div>
The "Time" property is of type DateTime, so when I click the dropdown list on my page I see full dates and times, but the thing is I want to display only the hours, without the dates, so I want to use something like Time.ToString("H:mm") but I don't know where can I write this so it will work. Maybe the right approach would be to add something like [Display(Name = Time.ToString("H:mm"))] annotation in my ClosingHour Model? I'm not sure if it's possible.
My View Model:
public class CinemaFormViewModel
{
public int? Id { get; set; }
[Required]
[StringLength(255)]
public string Name { get; set; }
[Required]
public string Address { get; set; }
[Required]
[Display(Name = "Total Seats")]
public int TotalSeats { get; set; }
public IEnumerable<OpeningHour> OpeningHours { get; set; }
[Required]
[Display(Name = "Opens At")]
public byte? OpeningHourId { get; set; }
public IEnumerable<ClosingHour> ClosingHours { get; set; }
[Required]
[Display(Name = "Closes At")]
public byte? ClosingHourId { get; set; }
}
My ClosingHour Model:
public class ClosingHour
{
public byte Id { get; set; }
[Required]
public DateTime Time { get; set; }
}
The Action inside the controller which calls the view:
public ActionResult New()
{
var openingHours = _context.OpeningHours.ToList();
var closingHours= _context.ClosingHours.ToList();
var viewModel = new CinemaFormViewModel
{
OpeningHours = openingHours,
ClosingHours = closingHours
};
return View("CinemaForm", viewModel);
}
change you by adding string time property
public class ClosingHour
{
public byte Id { get; set; }
[Required]
public DateTime Time { get; set; }
[NotMapped]
public string ShortTime { get; set; }
}
action
public ActionResult New()
{
var closingHours= _context.ClosingHours.ToList();
var openingHours = _context.OpeningHours.ToList();
closingHours.ForEach(i=> i.ShortTime=i.Time.ToShortTimeString());
openingHours.ForEach(i=> i.ShortTime=i.Time.ToShortTimeString());
// or you can try
closingHours.ForEach(i=> {
i.ShortTime=i.Time.ToShortTimeString();
i.Time=null;
});
openingHours.ForEach(i=> {
i.ShortTime=i.Time.ToShortTimeString();
i.Time=null;
});
var viewModel = new CinemaFormViewModel
{
OpeningHours = openingHours,
ClosingHours = closingHours
};
return View("CinemaForm", viewModel);
}
view
....
#Html.DropDownListFor(c => c.ClosingHourId,
new SelectList(Model.ClosingHours, "Id", "ShortTime"), "Select time", new { #class = "form-control" })
.....
I'm working on an ASP.NET MVC project. I have created the various models and the viewmodels to use in my project. I have also seeded my database table with seed data but upon implementing the registration view, I tested the form but was getting 0 as the value inserted into the Id portion of the database table. I truncated the tables and did a fresh new insert I still had same error.
Below is the model for the user table
public class User
{
[Key]
public byte Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string RefIndicator { get; set; }
public Team TeamCategory { get; set; }
public byte TeamId { get; set; }
public bool IsRegistered { get; set; }
public DateTime DateRegistered { get; set; }
public DateTime? LastModified { get; set; }
public UserRoles UserRoles { get; set; }
public byte UserRolesId { get; set; }
}
and below is the viewModel I created for the Team Model property I needed to use in my view
public class RegisterFormViewModel
{
public User Users { get; set; }
public byte Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public IEnumerable<Team> Teams { get; set; }
public byte TeamId { get; set; }
public string RefIndicator { get; set; }
public bool IsRegistered { get; set; }
public DateTime DateRegistered { get; set; }
public byte UserRolesId { get; set; }
}
And here is the register action to the userController to initialize the values for the Register view
public ActionResult Register()
{
var AppUser = User.Identity.Name.Substring(5);
var AppUserEmail = AppUser + "#nlng.com";
int index = AppUser.IndexOf('.');
var FirstName = AppUser.Substring(0, index);
var LastName = AppUser.Substring(index + 1);
var IsRegistered = true;
var UserRolesId = 1;
var DateRegistered = HttpContext.Timestamp;
var teams = _context.Team.ToList();
var viewModel = new RegisterFormViewModel{
Email = AppUserEmail,
FirstName = FirstName,
LastName = LastName,
Teams = _context.Team.ToList(),
IsRegistered = IsRegistered,
UserRolesId = (byte)UserRolesId,
DateRegistered = DateRegistered
};
return View("Register", viewModel);
}
And finally here is the associated view for the registration page
#model eLeave.ViewModel.RegisterFormViewModel
#{
ViewBag.Title = "Register";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>User Registration</h2>
#using (Html.BeginForm("Save", "User"))
{
<div class="form-group">
#Html.LabelFor(r=>r.FirstName)
#Html.TextBoxFor(r => r.FirstName, new { #class = "form-control", #readonly = true })
</div>
<div class="form-group">
#Html.LabelFor(r => r.LastName)
#Html.TextBoxFor(r => r.LastName, new { #class = "form-control", #readonly = true })
</div>
<div class="form-group">
#Html.LabelFor(r => r.Email)
#Html.TextBoxFor(r => r.Email, new { #class = "form-control", #readonly = true })
</div>
<div class="form-group">
#Html.LabelFor(r => r.TeamId)
#Html.DropDownListFor(r => r.TeamId, new SelectList(Model.Teams, "Id", "TeamName"), "Select your Team", new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(r => r.RefIndicator)
#Html.TextBoxFor(r => r.RefIndicator, new { #class = "form-control" })
</div>
#Html.HiddenFor(m => m.IsRegistered)
#Html.HiddenFor(m => m.DateRegistered)
#Html.HiddenFor(m => m.UserRolesId)
#Html.HiddenFor(m => m.Id)
#Html.AntiForgeryToken()
<button class="btn btn-primary">Register</button>
}
Finally here's the save action of the userController
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Save(User user)
{
if (!ModelState.IsValid)
{
var viewModel = new RegisterFormViewModel
{
Users = user,
Teams = _context.Team.ToList()
};
return View("Register", viewModel);
}
if (user.Id == 0)
{
_context.User.Add(user);
}
else
{
var usersInDb = _context.User.Single(m => m.Id == user.Id);
usersInDb.FirstName = user.FirstName;
usersInDb.LastName = user.LastName;
usersInDb.TeamCategory = user.TeamCategory;
usersInDb.RefIndicator = user.RefIndicator;
usersInDb.UserRoles = user.UserRoles;
usersInDb.IsRegistered = user.IsRegistered;
usersInDb.Email = user.Email;
usersInDb.DateRegistered = user.DateRegistered;
}
_context.SaveChanges();
return RedirectToAction("Index", "User");
}
The Save Action basically does two things...It saves a new form and it's also used for updating data.
Would appreciate if the bugs in my code can be fished out.
Form what I understand, you need to make ID as auto incremented value.
public class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string RefIndicator { get; set; }
public Team TeamCategory { get; set; }
public byte TeamId { get; set; }
public bool IsRegistered { get; set; }
public DateTime DateRegistered { get; set; }
public DateTime? LastModified { get; set; }
public UserRoles UserRoles { get; set; }
public byte UserRolesId { get; set; }
}
I don't think it will work with byte, but you can use int for sure.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().Property(a => a.Id).HasKey(b => b.Id);
modelBuilder.Entity<User>().Property(a => a.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
I have an ASP.NET MVC app and I am using Entity framework.
I have a model named Propiedad and this have some virtual properties without Required attibute, in the view I have a dropdown for the virtual properties and when I do not select an option this tell me that I have to select an option.
I need that Grupo property does not need to select another option, that I can select the optionLabel without show me validator error message.
This is the model:
public class Propiedad
{
[Key]
public int Id { get; set; }
public virtual Entidad Entidad { get; set; }
public virtual PestanasPorEntidad Pestana { get; set; }
public virtual GrupoDePropiedades Grupo { get; set; }
public string Codigo { get; set; }
public string Nombre { get; set; }
public string TipoDeDatos { get; set; }
public bool Requerido { get; set; }
[Required]
public int Orden { get; set; }
public string Columna { get; set; }
}
This is part of the view (Create):
<div class="form-group">
#Html.LabelFor(model => model.Grupo, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(m => m.Grupo.Id, (SelectList)(ViewBag.PestanaList), "Ninguno", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Grupo)
</div>
</div>
This is part of the controller
private void SetGrupoListViewBag()
{
ViewBag.GrupoList = new SelectList(unitOfWork.GrupoDePropiedadesRepository.Get(), "id", "nombre");
}
// GET: /GlobalAdmin/Propiedades/Create
public ActionResult Create()
{
var propiedad = new Propiedad();
SetTipoDeDatosListViewBag();
SetEntidadListViewBag();
SetPestanaListViewBag();
SetColumnaListViewBag();
SetGrupoListViewBag();
var entidadId = Request["entidadId"] != null ? Convert.ToInt32(Request["entidadId"]) : -1;
if (entidadId != -1)
{
propiedad.Entidad = unitOfWork.EntidadRepository.GetById(entidadId);
return View(propiedad);
}
else
{
return View();
}
}
i have two tables called "Events" and "EventUser",
public partial class Event
{
public Event()
{
this.EventUsers = new HashSet<EventUser>();
this.Objects = new HashSet<Object>();
}
public int Id { get; set; }
public Nullable<int> CreatedBy { get; set; }
public Nullable<System.DateTime> StartTime { get; set; }
public Nullable<bool> IsShared { get; set; }
public Nullable<double> Budget { get; set; }
public virtual User User { get; set; }
public virtual ICollection<EventUser> EventUsers { get; set; }
public virtual ICollection<Object> Objects { get; set; }
}
and
public partial class EventUser
{
public Nullable<int> EventId { get; set; }
public Nullable<int> UserId { get; set; }
public bool IsAccepted { get; set; }
public int EUPK { get; set; }
public virtual Event Event { get; set; }
public virtual User User { get; set; }
}
when the parameter of UserId is passed to the action method i'm planing to display all the events that have invited to that UserId and the all other users who has invited to each of that event...
For a example if the parameter userId is 2; i want to display all the EventIds of userId 2 & for each EventId all the UserIds and other details..
I tried this & i've got some information about the events but not the list of users who have also invited for each event..
here is my action method;
public ActionResult Index(int UId)
{
ViewBag.NotCount = 1;
var result1 = from eu in db.EventUsers where eu.UserId == UId select eu;
var result2 = from eu1 in result1
join e in db.Events on eu1.EventId equals e.Id
select new MessageViewModel {
EventID1 = e.Id,
IsAccepted= eu1.IsAccepted,
CreatedBy = e.CreatedBy,
Budget = e.Budget,
};
return View(result2);
}
and my view is;
#{var counter = 1;}
#if (!Model.Any())
{
<div style="margin-left:550px;margin-top:200px">
<h2>"There are no notifications for you"</h2>
</div>
}
else {
foreach (var item in Model)
{
<div class="panel panel-info" style="width:700px;margin-left:400px">
×
<div class=" panel-heading">
<h3 class="panel-title">Notification #counter</h3>
</div>
<div class="panel-body"><p>Event #item.EventID1 is created by #item.CreatedBy .Budget of the event is #item.Budget <p>
#if (item.IsAccepted)
{
<p>You have accept the invitation!!!</p>
}
#if (!item.IsAccepted)
{
<p>You haven't accept the invitation yet!!!!</p>
}
#{counter++;}
</div>
</div>
}
and my viewmodel is;
public class MessageViewModel
{
public int EventID1 { get; set; }
public bool IsAccepted { get; set; }
public int? CreatedBy { get; set; }
public DateTime StartTime { get; set; }
public bool IsShared { get; set; }
public int ObjectID { get; set; }
public double? Budget { get; set; }
public IEnumerable<EventUser> Euser { get; set; }
// don't know if this is the
// right way to get list of userids
}
how can i overcome this problem??are there any approaches other than this if my approach is wrong??
If you're not using lazy loading, you have to specify relationships you want manually using the Include command. It's called "join" in the sql-like query syntax you're using.
You've included a join between Event and EventUser, but another join is required between EventUser and User, because User is a different entity.
I can't help you with the code, because we can't tell what the primary key on your User object is. But look at the join syntax you've already got in place, and add another join between EventUser and User, following the same format.
Newbie Q: I have existing data painting to the Edit screen.. but cannot get it to update. I can create and list(in other code), but doing something wrong on the update. I believe I am doing something wrong in the controller.. Save button actions back to Edit screen with no changes.
Controller Code:
public class CompeditorController : Controller
{
private readonly BodyBuilderDB _db;
public CompeditorController(BodyBuilderDB db)
{
_db = db;
}
[HttpGet]
public ActionResult Edit(int CompeditorId)
{
var model = _db.Compeditors.Single(d => d.CompeditorId == CompeditorId);
return View(model);
}
[HttpPost]
public ActionResult Change(EditCompViewModel viewModel)
{
var compeditor = new Compeditor();
var bodybuilderDB = _db.Compeditors;
{
if (ModelState.IsValid)
compeditor.CompeditorId = viewModel.CompeditorId;
compeditor.FirstName = viewModel.FirstName;
compeditor.MiddleInt = viewModel.MiddleInt;
compeditor.LastName = viewModel.LastName;
compeditor.StreetAddress = viewModel.StreetAddress;
compeditor.City = viewModel.City;
compeditor.State = viewModel.State;
compeditor.PostalCode = viewModel.PostalCode;
compeditor.HomePhone = viewModel.HomePhone;
compeditor.CellPhone = viewModel.CellPhone;
compeditor.Height = viewModel.Height;
compeditor.Weight = viewModel.Weight;
compeditor.EmailAddress = viewModel.EmailAddress;
_db.Entry(bodybuilderDB).CurrentValues.SetValues(compeditor);
_db.SaveChanges();
}
End of View Code:
<div class="editor-label">
#Html.LabelFor(model => model.Weight)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Weight)
#Html.ValidationMessageFor(model => model.Weight)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
Model:
using System;
using eManager.Core;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace eManager.Web2.Models
{
public class EditCompViewModel
{
[Key]
public int CompeditorId { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public string MiddleInt { get; set; }
public string StreetAddress { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
public string EmailAddress { get; set; }
public string HomePhone { get; set; }
public string CellPhone { get; set; }
[Required]
public int Height { get; set; }
[Required]
public int Weight { get; set; }
}
}
Add this before your Save Changes
_db.Entry(bodybuilderDB).State = EntityState.Modified;
Remove
var compeditor = new Compeditor();
compeditor.CompeditorId = viewModel.CompeditorId;
compeditor.FirstName = viewModel.FirstName;
compeditor.MiddleInt = viewModel.MiddleInt;
compeditor.LastName = viewModel.LastName;
compeditor.StreetAddress = viewModel.StreetAddress;
compeditor.City = viewModel.City;
compeditor.State = viewModel.State;
compeditor.PostalCode = viewModel.PostalCode;
compeditor.HomePhone = viewModel.HomePhone;
compeditor.CellPhone = viewModel.CellPhone;
compeditor.Height = viewModel.Height;
compeditor.Weight = viewModel.Weight;
compeditor.EmailAddress = viewModel.EmailAddress;
And change
_db.Entry(bodybuilderDB).CurrentValues.SetValues(compeditor);
To
_db.Entry(bodybuilderDB).CurrentValues.SetValues(viewModel);