0

The issue I'm trying to resolve is that I'm trying to convert a Winforms app that relies heavily on INotifyProperty based data binding to track and log changes to the model, enabling a separate 'Value changed' audit to be written to another table.

I've searched for quite a while on this one and can't seem to find an answer that doesn't reference samples / examples using Entity Framework.

I've bound the data to the form and can return the updated information using either the IFormCollection object, TryUpdateModelAsync(model) or just passing the model directly to the PostFunction. However, short of retrieving a copy of the original and changed model data then comparing the entities one property at a time (which is far from ideal), I can't seem to find a way of just identifying the changed values.

Is this even possible, is there a best practice for it and if so can someone direct me to a good reference source?

Current examples of post function to retrieve data:

public IActionResult Post_Client(ClientDataModel client) {

    Console.WriteLine(client.Surname);
    return RedirectToAction("Workspace");

}
public IActionResult Post_Client(IFormCollection formData) {

var client = new ClientDataModel();
    client.Surname = list.FirstOrDefault(a => a.Key == "Surname").Value;
    Console.WriteLine(client.Surname);
    return RedirectToAction("Workspace");

}

public IActionResult Post_Client() {

    var client = new ClientDataModel();
    TryUpdateModelAsync(client);

    Console.WriteLine(client.Surname);
    return RedirectToAction("Workspace");

}

How it worked in Winforms:

        public class ClientDataModel{
        private string _surname;
        public string Surname { get => _surname; set => _surname = value.Truncate(50); }
    }
    
    public class ClientBindingHelper:BaseNotifier{
        public ClientData Model {
            get {
                return this.objmodel;
            }
            set {
                this.objmodel = value;
            }
        }
        public string Surname {
            get {
                return this.Model.Surname;
            }
            set {
                this.Model.LogChange("Surname", this.Model.Surname, value);
                this.Model.Surname = value;
                base.NotifyPropertyChanged("Surname");
            }
        }

    }

And then on the form itself the bindinghelper object would be bound to the control:

    Private void BindData(){
        var helper = new ClientBindingHelper()
        txtSurname.DataBindings.Add("Text", myBindingHelper, "Surname");    
    }
DazzaJ
  • 3
  • 2
  • Does this answer your question? [EntityFramework Core: Get changes occured in entity and related data](https://stackoverflow.com/questions/53064528/entityframework-core-get-changes-occured-in-entity-and-related-data) – Igor Aug 10 '23 at 11:10
  • Hi, no unfortunately it doesn't, your link directly references EF and i'm looking for a solution that doesn't use that. Entity framework implementation isn't an option for me. – DazzaJ Aug 10 '23 at 11:17
  • I doubt there's a simple solution without using EF. Maybe you can get inspiration from the EF implementation, where the starting point is `DetectChanges` https://github.com/dotnet/efcore/blob/main/src/EFCore/ChangeTracking/ChangeTracker.cs#L265 – Philippe Aug 10 '23 at 11:46
  • The problem here is that web stacks like aps.net are designed to be stateless. The server will not be tracking the changes directly like it did when you had a "fat" client in windows forms. This means that when state is submitted from the client (browser) to the server (asp.net server) the code must then figure out what changed if you want to implement some type of logging that tracks changes in state. The code would then likely get the old state, apply the changes in state from the client, and then get that delta to log what changed. EF-Core will allow you to do this. (continued below). – Igor Aug 10 '23 at 13:47
  • Without EF Core you will need to roll your own solution or try to find some existing library that does this. As EF is a true and tested framework to manage state and changes in state using a data store which is where you capture the state I would use this as a solution if I were you. There might be other options but solutions I would avoid is implementing this at the data layer which might be possible using DB triggers. Again, I would avoid this for reasons like possible performance impacts, brittle code, hidden side effects, convoluted code base, just to name some. – Igor Aug 10 '23 at 13:49
  • No easy way. You can send two different objects to your front-end. Say, old & changed. So, if both are not same, you know what has changed in front-end, and can manage it that way? – r2018 Aug 10 '23 at 15:42
  • One thing that comes to my mind is using SignalR. Take a look at this post: https://stackoverflow.com/questions/50788100/in-asp-net-core-signalr-how-do-i-send-a-message-from-the-server-to-a-client. You can write your own NotifyService and track db changes and notify clients. SignalR has a javascript client library. – SoftwareDveloper Aug 10 '23 at 20:02
  • Is it prossible to share, how are you doing that steps, so that it can be investigated or reproduce in order to assist you further. – Md Farid Uddin Kiron Aug 11 '23 at 09:48
  • Hi, I've updated my question to show the methods I'm using to return the object in the ASP Post Function and also how I used INotifyPropertyChanged (implemented in the BaseNotifier class) and logged the change when the property value was updated – DazzaJ Aug 14 '23 at 13:03
  • Thank you to everyone who has commented. It appears I may be able to resolve the issue using Angular and the validation states such as .Touched and .Pristine. I'd still have to loop through the objects but wouldn't need to do a manual comparison against the original object Also as @SoftwareDveloper has suggested, I could potentially use SignalR notify functions to track a change and store a list of the entries for appending to the log on submit – DazzaJ Aug 14 '23 at 13:07

0 Answers0