JMarsch
JMarsch

Reputation: 21753

Overriding validation in Breezejs

Here is an interesting requirement. How would I solve this with Breezejs?

(note, using a SPA design based on and extremely similar to the one in John Papa's Angular + Breezejs Pluralsight course)

We have a business rule that says that when I add or edit customer phone number, I need to check the phone number to see if there is a different customer with the same number (can happen due to phone number reassignment, etc).

If I find that it is a dup, I need to prompt the user. The user has the option to say "yah, that's fine", and then the phone number will save anyway.

So, I get how to do a basic validation with BeforeSaveEntity, and to fail if I find the dup, but suppose the user checks the "save anyway" option. How do I include this "out of band", non-data row information in my save set so that I can override the server-side validation rule?

And also, I don't want this validation to look like a "normal" error to the user on save -- I want to detect that it was the phone number clash thing, so I can display the view that prompts them to override.

Upvotes: 0

Views: 146

Answers (1)

Jay Traband
Jay Traband

Reputation: 17052

Out of band data can be passed either by using the SaveOptions.tag property or by going to a separate named endpoint in your save call. i.e.

   var so = new SaveOptions({ tag: "Special kind of save with extra data" });
   return myEntityManager.saveChanges(null, so);

or

   var so = new SaveOptions({ resourceName: "SaveWithSpecialValidation", tag: "any special data" });
   return em.saveChanges(null, so);

In terms of how to return a special server side save validation

[HttpPost]
public SaveResult SaveWithSpecialValidation(JObject saveBundle) {
  // custom tag passed from the client
  var theTag = ContextProvider.SaveOptions.Tag;
  ContextProvider.BeforeSaveEntitiesDelegate = BeforeSaveWithException;
  return ContextProvider.SaveChanges(saveBundle);
}

private Dictionary<Type, List<EntityInfo>> BeforeSaveWithException(Dictionary<Type, List<EntityInfo>> saveMap) {
  List<EntityInfo> orderInfos;
  if (saveMap.TryGetValue(typeof(Order), out orderInfos)) {
    if (YourErrorCheckHere(orderInfos)) {
      var errors = orderInfos.Select(oi => {
        return new EFEntityError(oi, "WrongMethod", "My custom exception message",        "OrderID");
      });
      // This is a special exception that will be forwarded correctly back to the client.
      var ex =  new EntityErrorsException("test of custom exception message", errors);
      // if you want to see a different error status code use this.
      // ex.StatusCode = HttpStatusCode.Conflict; // Conflict = 409 ; default is Forbidden (403).
      throw ex;
    }
  }
  return saveMap;
}

Hope this makes sense. :)

Upvotes: 2

Related Questions