0

I am working on an ASP.Net MVC app and I want to show a confirmation page after the user edits some data. What I would like to show is a list of the pending changes that the user made to the model. For example,

Are you sure you want to make the following changes:

FieldName:
   Previous Value: XXX
   New Value: YYY

I know I can read my stored value from the database and compare it with the POSTed object but I want this to work generally. What would be some good ways to approach this?

To clarify, I am looking for a general way to get a "diff" of the pending changes. I already know how to get the previous and pending changes. Kind of like how TryUpdateModel() can attempt to update any Model with posted values. I'd like a magical GetPendingModelChanges() method that can return a list of something like new PendingChange { Original = "XXX", NewValue = "YYY"} objects.

PPC-Coder
  • 3,522
  • 2
  • 21
  • 30

3 Answers3

1

Coming in very late here, but I created a library to do this on MVC models and providing "readable" diffs for humans using MVC ModelMetadata:

https://github.com/paultyng/ObjectDiff

It gives me output when I save a Model similar to:

Status: 'Live', was 'Inactive'  
Phone: '123-456-7898', was '555-555-5555'

Etc.

Paul Tyng
  • 7,924
  • 1
  • 33
  • 57
1

You might be doing this already but I wouldn't send my model to the view, create a viewmodel. In this case I would map the model data to the viewmodel twice, my viewmodel might contain OrderInput and OrderInputOrig. Then stick OrderInputOrig in hidden fields. On post back you can compare the values and then redirect, if something changed, to a display view with the original and the changes for confirmation.

Maybe something like this:

[HttpPost]
public ActionResult Edit(CustomerInput cutomerInput)
{
    var changes = PublicInstancePropertiesEqual(cutomerInput.OriginalCustomer, cutomerInput.Customer);

    if (changes != null)
    {
        cutomerInput.WhatChangeds = changes;
        return View("ConfirmChanges", cutomerInput);
    }

    return View();
}

public ActionResult ConfirmChanges(CustomerInput customerInput)
{
     return View(customerInput);
}

from: Comparing object properties in c#

public static Dictionary<string, WhatChanged> PublicInstancePropertiesEqual<T>(T self, T to, params string[] ignore) where T : class
{
    Dictionary<string, WhatChanged> changes = null;

    if (self != null && to != null)
    {
        var type = typeof(T);
        var ignoreList = new List<string>(ignore);
        foreach (System.Reflection.PropertyInfo pi in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
        {
            if (!ignoreList.Contains(pi.Name))
            {
                var selfValue = type.GetProperty(pi.Name).GetValue(self, null);
                var toValue = type.GetProperty(pi.Name).GetValue(to, null);

                if (selfValue != toValue && (selfValue == null || !selfValue.Equals(toValue)))
                {
                    if (changes == null)
                        changes = new Dictionary<string, WhatChanged>();

                    changes.Add(pi.Name, new WhatChanged
                                         {
                                            OldValue = selfValue,
                                            NewValue=toValue
                                         });
                }
            }
        }    
        return changes;
    }
    return null;
}
Community
  • 1
  • 1
Derek Beattie
  • 9,429
  • 4
  • 30
  • 44
  • Thanks, I can see using a ViewModel to hold the original and new values. What I'm really looking for is how to do the "if something changed" part in a general way. – PPC-Coder Mar 26 '11 at 14:51
  • Have the type used for OrderInput and OrderInputOrig implement IComparable. – Derek Beattie Mar 26 '11 at 14:56
  • I'm not quite sure how IComparable would help here. I'm not really comparing two objects but want the differences of their fields. – PPC-Coder Mar 26 '11 at 15:23
0

use the TempData Dictionary.

 TempData["previousValue"];
 TempData["newValue"];
Sarzniak
  • 297
  • 4
  • 10