I am trying to implement an Audit trail in my mvc web app, the Add and Delete is easy to implement, but I have a problem in Editing an existing record.
Basically, for each editing, I need to compare each field between current UI field value and the existing value in database, and create a change log in Log table.
so I am trying to do something like this:
[HttpPost]
public ActionResult Edit(ProdViewModel viewModel, string button)
{
ProdViewModel OrigAIGModel = viewModel; //I want to keep the original model data for comparing later,
tbl_Production NewProdModel = null;
.......
try
{
if (ModelState.IsValid)
{
int prodID= viewModel.SaveChanges(); //Update the record
if (prodID > 0)
{
//after successful update above, I need to compare the data below and create a audit trail.
// UpdateAuditTrail(ProdViewModel,NewProdModel.GetByID(prodID));
//here I expect to pass the old model data and new model data,
//But the ProdViewModel is not the old model data, it is the updated model data, the ProdViewModel and NewProdModel is equivelent,
return RedirectToAction("Edit", new { id = ProdID });
}
}
return View(viewModel);
Is there any way to keep the original model data before the "viewModel.SaveChanges(); ", so I can compare the two models (old model and new model ) data for auditing purpose?
Retrieve the entity from the database first thing in your POST method.
var fetched = db.Table.Find(id);
if(fetched.Field != posted.Field)
{
...do something to log
fetched.Field = posted.Field
}
Then just remember to update the fetched entry to the database (instead of the posted one).
db.entry(fetched).State = EntityState.Modified;
db.SaveChanges();
Mark all posts that give the desired result the answer. If you only mark the last that gave you clarification because you misread an earlier post others will be confused. Some of us are here to help others and our point to post ratio matters.
for an update, your code should lookup the old entity by the encrypted key passed by the post back view model. then apply the post back view model values that are allowed to be modified by the user to the entity. You can then use change tracking for audit.
then save changes.
hint: you can use attributes and reflection to apply changes from the view model to the entity model, or use a tool like automapper.
for an update, your code should lookup the old entity by the encrypted key passed by the post back view model. then apply the post back view model values that are allowed to be modified by the user to the entity. You can then use change tracking for audit.
then save changes.
hint: you can use attributes and reflection to apply changes from the view model to the entity model, or use a tool like automapper.
Sounds this is a better way, I appreciate if you can provide an example based on my example codes provided, much appreciated,
Member
366 Points
2214 Posts
How keep the original model data when execute an Edit on MVC?
Apr 15, 2019 06:35 PM|Peter Cong|LINK
I am trying to implement an Audit trail in my mvc web app, the Add and Delete is easy to implement, but I have a problem in Editing an existing record.
Basically, for each editing, I need to compare each field between current UI field value and the existing value in database, and create a change log in Log table.
so I am trying to do something like this:
Is there any way to keep the original model data before the "viewModel.SaveChanges(); ", so I can compare the two models (old model and new model ) data for auditing purpose?
Or if there is any other better solutions?
Any help is highly appreciated!
All-Star
53711 Points
24036 Posts
Re: How keep the original model data when execute an Edit on MVC?
Apr 15, 2019 07:09 PM|mgebhard|LINK
This should be handled in the database using an UPDATE trigger.
Google has a lot of information on the subject
https://stackoverflow.com/questions/12137102/sql-update-trigger-only-when-column-is-modified
SQL UPDATE Trigger reference
https://docs.microsoft.com/en-us/sql/t-sql/functions/update-trigger-functions-transact-sql?view=sql-server-2017
Contributor
7058 Points
2189 Posts
Re: How keep the original model data when execute an Edit on MVC?
Apr 15, 2019 07:28 PM|ryanbesko|LINK
Retrieve the entity from the database first thing in your POST method.
var fetched = db.Table.Find(id);
if(fetched.Field != posted.Field)
{
...do something to log
fetched.Field = posted.Field
}
Then just remember to update the fetched entry to the database (instead of the posted one).
db.entry(fetched).State = EntityState.Modified;
db.SaveChanges();
All-Star
58474 Points
15789 Posts
Re: How keep the original model data when execute an Edit on MVC?
Apr 15, 2019 07:33 PM|bruce (sqlwork.com)|LINK
you should also and an update timestamp, to test if the save was done after the page read, and page post back.
Member
366 Points
2214 Posts
Re: How keep the original model data when execute an Edit on MVC?
Apr 15, 2019 07:35 PM|Peter Cong|LINK
It seems the Update trigger is doing some coding in SQL side, no quite understand how to apply it in my situation,
I am wondering if there is any way to do it in controller side based on the C# codes I posted.
Thanks a lot,
All-Star
58474 Points
15789 Posts
Re: How keep the original model data when execute an Edit on MVC?
Apr 15, 2019 09:43 PM|bruce (sqlwork.com)|LINK
for an update, your code should lookup the old entity by the encrypted key passed by the post back view model. then apply the post back view model values that are allowed to be modified by the user to the entity. You can then use change tracking for audit. then save changes.
hint: you can use attributes and reflection to apply changes from the view model to the entity model, or use a tool like automapper.
Member
366 Points
2214 Posts
Re: How keep the original model data when execute an Edit on MVC?
Apr 15, 2019 10:25 PM|Peter Cong|LINK
Sounds this is a better way, I appreciate if you can provide an example based on my example codes provided, much appreciated,
Member
366 Points
2214 Posts
Re: How keep the original model data when execute an Edit on MVC?
Apr 16, 2019 06:40 PM|Peter Cong|LINK
Thank you so much, this is an easy and simple solution, works very well.