3

im working with breezejs, and the server-side code of my app is .net.

in my views (client side), i want to add and entity then i want to save it. Lets assume that an entity is like this :

{
  "Id": 1,
  "Name": "someName",
  "CreatedDate": "1900-01-01T05:00:00Z",
  "UpdatedDate": "1900-01-01T05:00:00Z",
  "CreatedBy": null,
  "UpdatedBy": null,
  "RowVersion": 0,
   etc ...
  }
}

i want to set the values of CreatedDate UpdatedDate CreatedBy and UpdatedBy, i can do that using javascript of course, BUT i dont want the client to take care of those kind of things.

my breeze controller where lives this function is like this:

[HttpPost]
public SaveResult SaveChanges(JObject saveBundle)
{
    return _contextProvider.SaveChanges(saveBundle);
 }

as u can see the saveBundle is a JObject, when i debug i see the saveBundle like this:

{
"entities": [
{
  "Id": 1,
  "Name": "someName",
  "CreatedDate": "1900-01-01T05:00:00Z",
  "UpdatedDate": "1900-01-01T05:00:00Z",
  "CreatedBy": null,
  "UpdatedBy": null,
  "RowVersion": 0,
   etc ...
    }
  }
}
],
"saveOptions": {}
}

How can i change the values of CreatedDate UpdatedDate CreatedBy and UpdatedBy in the saveBundle before the save is commited ???

this is a JObject with an array of objects as proprety, i can manipulate Json with javascript, how can i do it with .Net ???

Thanks a lot.

dafriskymonkey
  • 2,189
  • 6
  • 25
  • 48

2 Answers2

5

Thanks to Jay Traband post I finally found a way to make changes to an entity before saving it.

I overloaded the BeforeSaveEntity like this :

protected override bool BeforeSaveEntity(EntityInfo entityInfo) {
        // Return false if don´t want to  save the entity
        var entityType = entityInfo.Entity.GetType();

        if (entityInfo.Entity.GetType() == typeof(MyEntityTypeModel))
        {
            if (entityInfo.EntityState == EntityState.Added)
            // It can be 'Modified' or 'Deleted'
            {
                var MyModel = entityInfo.Entity as MyEntityTypeModel;

                MyModel.CreatedDate = DateTime.Now;
                MyModel.UpdatedDate = DateTime.Now;
                string username = Membership.GetUser().UserName;
                MyModel.CreatedBy = username;
                MyModel.UpdatedBy = username;
            }
        }
        return true;
   }

Thanks a lot, and I hope this will help someone someday.

dafriskymonkey
  • 2,189
  • 6
  • 25
  • 48
  • I was running around with the same problem and everywhere I see the answer is 'BeforeSaveEntities'. I doubt that this introduce a design-level problem because we are forced to do all business-level manipulations inside the DataContextProvider, which should ideally have been done inside the repository. What if we have 10+ such entities to modify before save? Are we going to use a swich-case to check the entity type and do the modifications? What is the best practice we can follow? – devC Feb 18 '15 at 08:57
  • Note that you would also need to update the OriginalValuesMap when modifying an Entity, e.g. entityInfo.OriginalValuesMap["UpdatedDate"] = null; more info here -> http://breeze.github.io/doc-net/contextprovider.html#OriginalValuesMap – JSancho Jan 13 '16 at 11:12
3

You can intercept Breeze's server side save process by using the ContextProvider's virtual BeforeSaveEntity and BeforeSaveEntities methods. The documentation here and here has more information on this topic.

For example, you can override BeforeSaveEntities with code something like the following.

protected override Dictionary<Type, List<EntityInfo>> BeforeSaveEntities(Dictionary<Type, List<EntityInfo>> saveMap) {

   foreach (var type in saveMap.Keys) {
     var list = saveMap[type];
      foreach (var entityInfo in list) {
         var entity = entityInfo.Entity;
         // .. do something interesting here
      }
 }
Jay Traband
  • 17,053
  • 1
  • 23
  • 44