NOTE: This page is for Breeze running on .NET 4.x
Go here for .NET Core version
All server side validation errors go to the catch
promise. Server side validation errors appear as a property called entityErrors
that contains an array of server errors.
em.saveChanges().then(function (sr) {
…
}).catch(function (e) {
var entityErrors = e.entityErrors;
var entityErrors = entityErrors.length; // number of errors
// handle the errors...
});
Each client side entityError consists of the following properties:
EntityErrors that have an associated entity will also get converted into validationError instances and will get automatically added to the appropriate entityAspect validationErrors collections. The appropriate validationErrorsChanged events will then fire.
Server errors are automatically cleared before a save so that they don’t interfere with the save. Alternatively they can be removed via the entityAspect.removeValidationError method.
Server side validation errors can be returned in using .Net Validation Attributes or by throwing an EntityErrorsException within the server side BeforeSaveEntities delegate or virtual method.
These validations are automatically executed once declared. (Note this only works for EF DbContext’s (Database First or Code First); old ObjectContext code does not execute .NET validations).
// Example class and property level custom validators
[AttributeUsage(AttributeTargets.Class)]
public class CustomerValidator : ValidationAttribute {
public override Boolean IsValid(Object value) {
var cust = value as Customer;
if (cust != null && cust.CompanyName.ToLower() == "error") {
ErrorMessage = "This customer is not valid!";
return false;
}
return true;
}
[AttributeUsage(AttributeTargets.Property)]
public class CustomValidator : ValidationAttribute {
public override Boolean IsValid(Object value) {
try {
var val = (string)value;
if (!string.IsNullOrEmpty(val) && val.StartsWith("Error")) {
ErrorMessage = "{0} equal the word 'Error'";
return false;
}
return true;
} catch (Exception e) {
var x = e;
return false;
}
}
}
Code First
[CustomerValidator]
public partial class Customer {
[Column("ContactName")]
[CustomValidator]
public string ContactName { get; set; }
}
Database First
[MetadataType(typeof(CustomerMetaData))]
[CustomerValidator]
public partial class Customer {
}
public class CustomerMetaData {
[CustomValidator]
public string ContactName {
get;
set;
}
}
By throwing an EntityErrorsException within the server side BeforeSaveEntities delegate or virtual method. The EntityErrorsException ctor takes a IEnumerable of EntityError.
Each EntityError within this exception will be sent back to the Breeze client and converted into a client side ‘entityError’ within the promise.catch branch. The EntityError class consists of the following properties.
EFEntityError is an Entity Framework specific subclass of EntityError that makes it easier to construct an EntityError from an EFEntityInfo instance (available within the BeforeSaveEntity and BeforeSaveEntities methods). The EFEntityError constructor looks like:
EFEntityError(EFEntityInfo entityInfo, String errorName, String errorMessage, String propertyName);
Example:
[HttpPost]
public SaveResult SaveWithEntityErrorsException(JObject saveBundle) {
ContextProvider.BeforeSaveEntitiesDelegate = ThrowEntityErrorsException;
return ContextProvider.SaveChanges(saveBundle);
}
private Dictionary<Type, List<EntityInfo>> ThrowEntityErrorsException(Dictionary<Type, List<EntityInfo>> saveMap) {
List<EntityInfo> orderInfos;
if (saveMap.TryGetValue(typeof(Order), out orderInfos)) {
var errors = orderInfos.Select(oi => {
return new EFEntityError(oi, "WrongMethod", "Cannot save orders with this save method", "OrderID");
});
throw new EntityErrorsException(errors);
}
return saveMap;
}
All other errors thrown on the server, still go to the fail promise but without the “entityErrors” property.