1

I have the following JSON when user clicks save

tasks      : {
        updated : [
            { Id : 123, SomeField1 : 'new value', SomeField2 : 'new value', SomeField3 : 'new value' },
            { Id : 125, SomeField2 : 'new value' },
            { Id : 127, SomeField1 : 'new value', SomeField4 : 'new value' },
            { Id : 129, SomeField2 : 'new value', SomeField3 : 'new value' },
            { ................ }
        ],
        removed : [
            { Id : 345 },
            { Id : 847 }
        ]
    }

on the MVC server side (C#), I have a ViewModel and .NET deserializes this back to my viewmodel object. in this example, This object has Id, SomeField1, SomeField2, SomeField3, SomeField4.

The problem I am having is that the client only sends the fields which were actually updated, so If the user never updated SomeField3 it wont be in the json and .NET for that array object will have a null as SomeeField3 ...

so i cant get record, update all the fields to what the viewmodel is and then call an update as it will set SomeField3 to null , which is not correct - there could be data in that field which the user just didn't touch in this case .. (in another case they may have deleted their text, which then the update would be valid..

I am not sure what is the best way to tackle this problem. Looking forward to your suggestions.

Cranzy
  • 49
  • 1
  • 8
  • are you using EF for saving record? – Komal Apr 03 '17 at 07:23
  • yes, EF(Code First) and UnitOfWork. – Cranzy Apr 03 '17 at 07:32
  • you can use .IsModified property for updated fields only to be changed in db like db.Entry(sometable).Property(x => x.somefield).IsModified = true; – Komal Apr 03 '17 at 07:35
  • on server side, I am getting the object and then assigning the values from the viewmodel to the object before calling the update. I kind of need to know a IsModified flag on the viewmodel for each property so i know if it was set by the deserializer or not... – Cranzy Apr 03 '17 at 07:48
  • yes its for the properties without null values to be updated. – Komal Apr 03 '17 at 08:14
  • Problem is the deserialization to the viewmodel (not the db object) .... problem is the json deserialized into viewmodel , all missing properties are null, I only need to update the fields sent via JSON, but .net deserializes it into a full viewmodel object, so there are many irrelevant fields.. – Cranzy Apr 03 '17 at 08:39
  • viewmodel defined with the fields which are not in json? – Komal Apr 03 '17 at 09:06

2 Answers2

0

I suggest you to post updated string in API action, then you can get your solution as : Create dynamic property mapping function :

    public static class DynamicToStatic
    {
     public static T ToStatic<T>(object source, T destination)
     {
        var entity = destination;

        //source implements dictionary
        var properties = source as IDictionary<string, object>;

        if (properties == null)
            return entity;

        foreach (var entry in properties)
        {
            var propertyInfo = entity.GetType().GetProperty(entry.Key);
            if (propertyInfo != null && entry.Value != null)//Check property and its values exist or not ,change only when source contains value
                propertyInfo.SetValue(entity, entry.Value, null);
        }
        return entity;
    }
 }

Convert your request json to dynamic object and then map dynamic object to Your static class type model, Class type model initialized from your db record or any source as per your requirement.

//updatedJsonObjectString bound from request post data(JSONSTRINGIFY of post data)
dynamic source = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(updatedJsonObjectString);
Class1 model = new Class1();//mapped/filled by data call
var retUser = DynamicToStatic.ToStatic<Class1>(source, model);
Jignesh Variya
  • 1,869
  • 16
  • 12
  • Hi The Json that gets sent by this client tool is added, updated and deleted all in one json request (not sure I can change this) .. So I have an object public class SchedulerHelperSaveObject { public IEnumerable added { get; set; } public IEnumerable updated { get; set; } public IEnumerable removed { get; set; } } and then my viewmodel uses this view tasks or whatever im processing, I have the added and removed all working, it is just the edit which is currently giving me some gray hairs. – Cranzy Apr 03 '17 at 07:45
  • You can follow same approach as above, you can set your logic in DynamicToStatic.ToStatic() implementation. – Jignesh Variya Apr 03 '17 at 07:48
  • Just struggling at the moment to get the updated records to be passed as string, as the api sending the data is 3rd party so I just receive the records via json as i showed in the question .. it sends tasks, employees and each of those have array of (added, updated, deleted).. and my viewmodel on my mvc Action has properties like this. – Cranzy Apr 04 '17 at 03:53
  • public IEnumerable added { get; set; } public IEnumerable updated { get; set; } public IEnumerable removed { get; set; } – Cranzy Apr 04 '17 at 03:53
  • if I change the updated to ienumberable it just doesnt seem to work – Cranzy Apr 04 '17 at 03:54
0

if you are using Newton Json for Deserializing. Newton Json DeserializeObject method has an overload which takes json string and JsonSerializerSettings as parameters. JsonSerializerSettings has NullValueHandling and MissingMemberHandling properties.

  • MissingMemberHandling: Gets or sets how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization.

  • NullValueHandling: Gets or sets how null values are handled during serialization and deserialization

mmushtaq
  • 3,430
  • 7
  • 30
  • 47