Amour Rashid
Amour Rashid

Reputation: 310

Return meaningful error message while calling SaveChanges in Breeze

I am using ASP.NET WebAPI 2 with Breeze. I want to be able to return meaningful error messages when saving changes using SaveChanges() method. This is in case there is an error. The current implementation returns SaveResult. How can return message e.g

var cardDetail = _membershipContextProvider.Context.Database.SqlQuery<CardDetail>("IssuedCardsGetVerificationDetails @CardNo", parameter).FirstOrDefault();
        if (cardDetail == null)
        {
            HttpResponseMessage msg = new HttpResponseMessage(HttpStatusCode.NotFound)
            {
                Content = new StringContent(string.Format("The beneficiary with Card No. {0} was found in the NHIF database", CardNo)),
                ReasonPhrase =string.Format("Card No. {0} Not Found in the NHIF Database!",CardNo)
            };
            throw new HttpResponseException(msg);
        }
        return cardDetail;

Upvotes: 1

Views: 296

Answers (1)

Jay Traband
Jay Traband

Reputation: 17052

You need to throw an EntityErrorsException within the custom save method. This exception lets you both specify a top level message as well as a custom message for each failed entity.

[HttpPost]
public SaveResult MyCustomSaveMethod(JObject saveBundle) {
  ContextProvider.BeforeSaveEntitiesDelegate = SaveThatMightThrow;
  return ContextProvider.SaveChanges(saveBundle);
}


private Dictionary<Type, List<EntityInfo>> SaveThatMightThrow(Dictionary<Type,    List<EntityInfo>> saveMap) {
    List<EntityInfo> orderInfos;
    // if this save tries to save ANY orders throw an exception.
    if (saveMap.TryGetValue(typeof(Order), out orderInfos)) {
      var errors = orderInfos.Select(oi => {
        return new EFEntityError(oi, "WrongMethod", "Entity level detail error - Cannot save orders with this save method", "OrderID");
      });
      var ex =  new EntityErrorsException("Top level error - Orders should not be saved with this method", 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;
  }

Note that there is a bug in Breeze 1.4.16 where the top level error is not being propagated properly (it returns to the client as an empty string), however the entity level error messages will come thru just fine. This bug has been fixed in the latest GitHub repos, but you will need to get the fixed code from both the breeze.js and the breeze.server.net repos because the fix was to both the breeze.js client as well as the ContextProvider class in breeze.server.net. Or you can wait for the next breeze release in about a week.

Upvotes: 2

Related Questions