MVC Automapper update - asp.net-mvc

i tried to update my database table some fields
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(MemberTasks membertaskdetails)
{
if (ModelState.IsValid)
{
MemberTasks Mtasks = db.MemberTask.Find(membertaskdetails.id);
Mtasks.Taskid = membertaskdetails.Taskid;
Mtasks.status = membertaskdetails.status;
AutoMapper.Mapper.Map(membertaskdetails,Mtasks);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(membertaskdetails);
}
ViewModel
public class MemberTasks
{
[Key]
[Display(Name = "ID")]
public int id { get; set; }
[Display(Name = "Task ID")]
public int Taskid { get; set; }
[Display(Name = "Status")]
public int status { get; set; }
[Display(Name = "Created By")]
public string createdby { get; set; }
[Display(Name = "Team Lead")]
public string TeamLead { get; set; }
[Display(Name = "Note")]
public string Note { get; set; }
[Display(Name = "Members")]
public string Membersid { get; set; }
}
Code is executed successfully but the problem is remaining fields also updated with null value i have 6 columns i want to update 2 columns only.
Any help ?

Your source and destination object used in AutoMapper are of the same type (MemberTasks). That's not how AutoMapper is supposed to be used. AutoMapper is used to map between domain models and view models.
So you must have a view model containing the properties passed from the view:
public class MemberTasksViewModel
{
public int Id { get; set; }
public int Taskid { get; set; }
public int Status { get; set; }
}
and then:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(MemberTasksViewModel viewModel)
{
if (ModelState.IsValid)
{
MemberTasks domainModel = db.MemberTask.Find(viewModel.Id);
Mapper.Map(viewModel, domainModel);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(viewModel);
}

Related

How to add two values ​from related tables in ASP.NET MVC 5

I apologize for the question, but I'm still not good at ASP.NET MVC 5, I ask for help, the task is as follows:
There is a database with two related tables, RequestProcessing and RequestType. The value of the DeadLine column of the RequestProcessing table should change depending on the TimeComplete value of the RequestType table, namely, it consists of the values
​​RequestProcessing.DeadLine = RequestProcessing.Date + RequestType.TimeComplete
I apologize for such rude formulations. Below I give the classes themselves and the controller method in which I want to get this
public class RequestProcessing
{
public int Id { get; set; }
[Display(Name = "Дата поступления")]
[Required]
public DateTime Date { get; set; }
[Display(Name = "Комментарий")]
public string Comment { get; set; }
[Display(Name = "Выполнить до")]
[Required]
public DateTime DeadLine { get; set; }
[Display(Name = "ИД заявки")]
[Required]
public int RequestId { get; set; }
public Request Request { get; set; }
[Display(Name = "ФИО")]
public int? SpecialistId { get; set; }
public Specialist Specialist { get; set; }
[Display(Name = "Статус заявки")]
public int? StatusId { get; set; }
public Status Status { get; set; }
[Display(Name = "Тип заявки")]
public int? TypeId { get; set; }
[ForeignKey ("TypeId")]
public RequestType RequestType { get; set; }
}
public class RequestType
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Display(Name = "Тип заявки")]
[Required]
[StringLength(50, ErrorMessage = "Данное поле должно содержать не более 50 символов")]
public string TypeName { get; set; }
[Display(Name = "Время на выполнение")]
[Required]
public double TimeComplete { get; set; }
[Display(Name = "Описание")]
[StringLength(300, ErrorMessage = "Данное поле должно содержать не более 300 символов")]
public string Description { get; set; }
[ForeignKey("TypeId")]
public virtual ICollection<RequestProcessing> RequestProcessings { get; set; }
public RequestType()
{
RequestProcessings = new List<RequestProcessing>();
}
}
public class RequestProcessingController : Controller
{
[HttpPost]
public ActionResult EditRequestProcessing(RequestProcessing rProcessing)
{
if (ModelState.IsValid)
{
RequestProcessing newRProcessing = dbRP.RequestProcessings.Find(rProcessing.Id);
newRProcessing.Comment = rProcessing.Comment;
newRProcessing.SpecialistId = rProcessing.SpecialistId;
newRProcessing.StatusId = rProcessing.StatusId;
newRProcessing.TypeId = rProcessing.TypeId;
newRProcessing.DeadLine = rProcessing.Date.AddMinutes(rProcessing.RequestType.TimeComplete);
dbRP.Entry(newRProcessing).State = EntityState.Modified;
dbRP.SaveChanges();
return RedirectToAction("RequestProcessing");
}
return View();
}
}
Just use the include, and fill, and then iterate in your view
Your Action
public ActionResult EditRequestProcessing(RequestProcessing rProcessing)
{
if (ModelState.IsValid)
{
// ... do your stuff blah blah
// get related data
var relatedProcessingData = db.RequestProcessing.Include(p=>p.RequestType);
//...
}
...
}
In your view
#Html.DisplayFor(modelItem => item.relatedProcessingData.RequestType)
Edit/Update: I saw you wanted the dead line, just compute calculate that in your action with a new ViewModel Object.
I would recommend a create new ViewModel like so RequestProcessingDeadLineViewModel
public class RequestProcessingDeadLineViewModel
{
public int Id { get; set; }
// Fill this in your business layer
public List<DateTime> DeadLine { get ; set; }
}
Or in the action
public ActionResult EditRequestProcessing(RequestProcessing rProcessing)
{
if (ModelState.IsValid)
{
// ... do your stuff blah blah
// get related data
var relatedProcessingData = db.RequestProcessing.Include(p=>p.RequestType);
// new deadline VM
var deadLineVM = new RequestProcessingDeadLineViewModel();
// copy your data to your ViewModel
foreach(...)
deadLineVM.DeadLine = deadLineVM.Date + + deadLineVM.TimeComplete;
//...
}
...
}

Issue with One to Many on MVC

New to EF, MVC, and databases in general. If this is overly obvious just tell me what this is called exactly and I'd be glad to look it up on here.
I'm not able to apply information calculated from my Foreign Key to my Primary key.
In other words: I'm trying to calculate and apply a new AmountMade by a booth each time we "Sell" an Antique.
Booth Model:
public class Booth
{
public Booth()
{
Antiques = new List<Antique>();
}
[Required]
public int BoothId { get; set; }
[Required]
public string Owner { get; set; }
public double AmountMade { get; set; }
public Antique Antique {get;set;}
public virtual ICollection<Antique> Antiques{get;set;}
}
Antique Model:
public class Antique
{
[Required]
public int AntiqueId { get; set; }
[Required]
public string ItemName { get; set; }
[Required]
public double Price { get; set; }
public bool Sold { get; set; }
public int BoothId { get; set; }
[ForeignKey("BoothId")]
public virtual Booth Booth { get; set; }
}
AntiquesController:
// GET: Antiques/Sell/5
public ActionResult Sell(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Antique antique = db.Antiques.Find(id);
antique.Booth.AmountMade = antique.Booth.AmountMade + antique.Price; //Price of antique is added to Amount made
if (antique == null)
{
return HttpNotFound();
}
ViewBag.BoothId = new SelectList(db.Booths, "BoothId", "Owner", antique.BoothId);
return View(antique);
}
// POST: Antiques/Sell/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Sell([Bind(Include = "AntiqueId,ItemName,Price,BoothId")] Antique antique)
{
if (ModelState.IsValid)
{
db.Entry(antique).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
antique.Sold = true; //Mark as sold
ViewBag.BoothId = new SelectList(db.Booths, "BoothId", "Owner", antique.BoothId);
antique.Booth.AmountMade = antique.Booth.AmountMade + antique.Price; //Price of antique is added to Amount made
return View(antique);
}
This synchronization happens after Db.SaveChanges() is called, but I'm not sure can it be done before that by calling some other method.

Drop down list's selected value resets on form submit

When I go to edit a members Member Type by changing the drop down selected value, on postback the selected value resets itself to the top item and the user gets that member type.
Any ideas where I am going wrong?
View -
#Html.DropDownListFor(model => model.SelectedMemberType, new SelectList(Model.MemberTypes, "ID", "Name", (int)Model.MemberType))
Model -
public class MemberDetailModel
{
public int Id { get; set; }
public int CustomerId { get; set; }
[Required]
[DisplayName("First Name")]
public string FirstName { get; set; }
[Required]
[DisplayName("Last Name")]
public string LastName { get; set; }
public int SelectedMemberType { get; set; }
[Required]
[DisplayName("Member Type")]
public int MemberType { get; set; }
public virtual IList<MemberTypeModel> MemberTypes { get; set; }
public MemberDetailModel()
{
MemberTypes = new List<MemberTypeModel>();
}
}
Controller -
[Authorize]
public ActionResult Details(int id = 0)
{
ViewBag.MemberType = new SelectList(_memberTypeService.GetAll(), "ID", "Name");
MemberDetailModel member = _memberService.GetById(id);
IEnumerable<Gender> genders = Enum.GetValues(typeof(Gender))
.Cast<Gender>();
return View(member);
}
[HttpPost]
public ActionResult Details(MemberDetailModel model)
{
model.MemberType = model.SelectedMemberType;
if (ModelState.IsValid)
{
_memberService.UpdateMember(model);
return View(member);
}
return View(model);
}
As selectlist will be lost between postbacks, so just don't forget to set the MemberTypes again on postback. Most of the cases that is the issue.

Creating dropdownlist for entity in MVC

I'm new to MVC and are having a hard time figuring some "basic" things out.
I have a ViewModel shaped as follows:
public class ProjectViewModel
{
public int Id { get; set; }
[Required]
public string Title { get; set; }
[Required]
public string Description { get; set; }
public DateTime CreatedDate { get; set; }
[Required]
[Display(Name = "Final due date")]
public DateTime FinalDueDate { get; set; }
[Required]
[Display(Name = "Attached equipment")]
public Equipment AttachedEquipment { get; set; }
}
In my Create view I would like to be able to select the value for AttachedEquipment from a dropdownlist. I have a table in my database with all the available Equipments.
I know there is an #Html helper #Html.DropDownListFor which serves this very purpose. However I fail to see how I get the values from the database and spit them out into my view.
My ProjectController looks like this:
private AdventureWorks db = new AdventureWorks();
// GET: Project
public ActionResult Index()
{
return View();
}
[HttpGet]
public ActionResult Create()
{
// I'm guessing this is where I need to do some magic
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ProjectViewModel model)
{
if (ModelState.IsValid)
{
var project = new Project
{
Title = model.Title,
Description = model.Description,
CreatedDate = DateTime.Now,
FinalDueDate = model.FinalDueDate,
Equipment = model.Equipment
};
db.Projects.Add(project);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(model);
}
How do I load the Equipment values from my DB into a dropdownlist in my Create view?
Since you cant bind a dropdownlist to the complex object AttachedEquipment, I would change the view model to include properties for the selected equipment and a SelectList for the options
public class ProjectViewModel
{
public int Id { get; set; }
[Required]
public string Title { get; set; }
[Required]
public string Description { get; set; }
public DateTime CreatedDate { get; set; }
[Required]
[Display(Name = "Final due date")]
public DateTime FinalDueDate { get; set; }
[Required(ErrorMessage="Please select equipment)]
public int? SelectedEquipment { get; set; }
public SelectList EquipmentList { get; set; }
}
Controller
public ActionResult Create()
{
ProjectViewModel model = new ProjectViewModel();
// Assumes your Equipments class has properties ID and Name
model.EquipmentList = new SelectList(db.Equipments, "ID", "Name");
return View(model);
}
View
#model ProjectViewModel
#using(Html.BeginForm())
{
....
#Html.DropDownListFor(m => m.SelectedEquipment, Model.EquipmentList, "--Please select--")
....
}
Alternatively you can bind to m => m.AttachedEquipment.ID (assuming Equipment contains property ID)

Model or ViewModel in a ListViewModel

Should T be a for example Customer or CustomerViewModel ?
The annotations bound to Mvc namespace are on the ListViewModel so actually I could pass the Customer object. What do you think?
public class ListViewModel<T>
{
[Required(ErrorMessage="No item selected.")]
public int[] SelectedIds { get; set; }
public IEnumerable<T> DisplayList { get; set; }
}
UPDATE
[HttpGet]
public ActionResult Open()
{
IEnumerable<Testplan> testplans = _testplanDataProvider.GetTestplans();
OpenTestplanListViewModel viewModel = new OpenTestplanListViewModel(testplans);
return PartialView(viewModel);
}
public class OpenTestplanListViewModel
{
public OpenTestplanListViewModel(IEnumerable<Testplan> testplans)
{
var testplanViewModels = testplans.Select(t => new TestplanViewModel
{
Name = string.Format("{0}-{1}-{2}-{3}", t.Release.Name, t.Template.Name, t.CreatedAt, t.CreatedBy),
TestplanId = t.TestplanId,
});
DisplayList = testplanViewModels;
}
[Required(ErrorMessage = "No item selected.")]
public int[] SelectedIds { get; set; }
public string Name { get; set; }
public IEnumerable<TestplanViewModel> DisplayList { get; private set; }
}
public class TestplanViewModel
{
public int TestplanId { get; set; }
public string Name { get; set; }
}
public class Testplan
{
public int TestplanId { get; set; }
public int TemplateId { get; set; }
public int ReleaseId { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedAt { get; set; }
public Template Template { get; set; }
public Release Release { get; set; }
}
T should ideally be a view model. Having a view model referencing domain models is some kind of a hybrid view model, not a real one. But if you think that in this specific case the domain model will be exactly the same as the view model then you could keep it as well.

Resources