I have a single view that handles a lot of Models of type VoyagesViewModel, in that view the user can create a new voyage or edit all the active voyages, so i have different instances of the same object type in that view. each form contains something like:
<% = Html.Hidden("Voyages["+ i +"].VoyageDetails[" + i2 + "].Id", location.Id)%>
<% = Html.TextBox("Voyages[" + i + "].VoyageDetails[" + i2 + "].ArrivalDate", location.ArrivalDate, new { @class = "dates" })%><% = Html.ValidationMessage("Voyages[" + i + "].VoyageDetails[" + i2 + "].ArrivalDate", "*")%>
<% = Html.TextBox("Voyages[" + i + "].VoyageDetails[" + i2 + "].DepartureDate", location.DepartureDate, new { @class = "dates" })%><% = Html.ValidationMessage("Voyages[" + i + "].VoyageDetails[" + i2 + "].DepartureDate", "*")%>
<% = Html.Hidden("Voyages[" + i + "].VoyageDetails[" + i2 + "].LocationID", location.LocationID)%>
<% = Html.Hidden("Voyages[" + i + "].VoyageDetails[" + i2 + "].LocationName", location.LocationName)%>
<% = Html.Hidden("Voyages[" + i + "].VoyageDetails[" + i2 + "].VesselName", location.VesselName)%>
<% = Html.Hidden("Voyages[" + i + "].VoyageDetails[" + i2 + "].VesselID", location.VesselID)%>
<% = Html.CheckBox("Voyages[" + i + "].VoyageDetails[" + i2 + "].remove", location.remove)%> (remove)
I have 8 to 10 of this in that View, when the user POST the form(I have all this fields in a single form), i want to be able to detect if the user change something in a voyage to save it, so i don't have to save that specific voyage if no changes where made.
To check this i have a hidden field and i do this:
<% = Html.Hidden("Voyages[" + i + "].hash", TamperProofing.GetExpiringHMAC(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model), DateTime.Now.AddMinutes(15)))%>
Im using HMAC to get a hashed version of the hole object, but first i serialize the object into a string format (JSON Format):
{"Id":22,"VesselName":"CAPTAIN P (CPP)","VesselID":8,"VoyageDetails":[{"Id":58,"ArrivalDate":"\/Date(1259298000000)\/","DepartureDate":"\/Date(1259384400000)\/","LocationID":404,"LocationHash":null,"LocationName":"Balboa, Panama (PABLB)","VesselName":"CAPTAIN P (CPP)","VesselID":8,"Order":0,"Comment":null,"remove":false},{"Id":60,"ArrivalDate":"\/Date(1260248400000)\/","DepartureDate":"\/Date(1260334800000)\/","LocationID":406,"LocationHash":null,"LocationName":"Colon Free Zone, Panama (PACFZ)","VesselName":"CAPTAIN P (CPP)","VesselID":8,"Order":0,"Comment":null,"remove":false},{"Id":61,"ArrivalDate":"\/Date(1260421200000)\/","DepartureDate":"\/Date(1260507600000)\/","LocationID":407,"LocationHash":null,"LocationName":"Cristobal, Panama (PACTB)","VesselName":"CAPTAIN P (CPP)","VesselID":8,"Order":0,"Comment":null,"remove":false},{"Id":62,"ArrivalDate":null,"DepartureDate":null,"LocationID":408,"LocationHash":null,"LocationName":"Manzanillo, Panama (PAMAN)","VesselName":"CAPTAIN P (CPP)","VesselID":8,"Order":0,"Comment":null,"remove":false},{"Id":59,"ArrivalDate":null,"DepartureDate":null,"LocationID":405,"LocationHash":null,"LocationName":"Coco Solo, Panama (PACSO)","VesselName":"CAPTAIN P (CPP)","VesselID":8,"Order":0,"Comment":null,"remove":true}],"newVoyageDetail":null,"isComplete":false,"Code":"A Code","position":0,"hash":null}
So when the user POST the form i check if changes where made to each voyage like this:
var obj = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(_voyage);
if (TamperProofing.VerifyChanges(obj, hash) == TamperProofing.HMACChanged.True)
{
//UPDATE
}else
{
//DO Nothing, is the exact same object
}
Serialize it again and compare both hashes, the one on the hidden against the recently calculated one, if it match it means nothing changed.
All works pretty well, i was just wondering, if there are any other options to do this?
And my other concern is the time that can take the serialization and all the HMAC thing with this large string generated by the Serialization against the time it could take just to Update unchanged object again to the DB.
EDIT: I don't need to know which field changed, just if something changed.