Server side validation with custom EFContextProvider

廉价感情. 提交于 2019-12-04 17:16:28

1) Typically the simplest way to return 'custom' validation errors from the server to the client is to simply throw an error on the server. What I have not tried but think might work is that if you want that error to be applied to a specific entity, create an exception that includes a property that contains the EntityKey's of the entity/entities that fail and throw this exception. On the client you should be able to retrieve this error, in the promise failure branch, and apply the validation error yourself to the specific entity. ( By the way, it does sound like a reasonable feature request for breeze to make this process easier. Please post it on the Breeze User Voice so we can gauge the community's interest.)

2) You have two methods to apply a 'context' to a save. The simplest is via the SaveOptions.tag property. This property can be set on the client and will be deserialized on the server for use within your ContextProvider via the SaveOptions property. (something like this):

 public class NorthwindContextProvider : EFContextProvider<NorthwindIBContext_EDMX_2012> {

    protected override bool BeforeSaveEntity(EntityInfo entityInfo) {
       if ((string)SaveOptions.Tag == "myCustomSaveSetting") {

       }
    }

The other approach is to create a completely separate endpoint for each 'version' of your save. You can do this via the 'resourceName' property of the SaveOptions instance.

 var so = new SaveOptions({ resourceName: "MyCustomSave" });
 return myEntityManager.saveChanges(null, so);

will go to the 'MyCustomSave' controller method instead of the standard "SaveChanges" method. i.e.

public class NorthwindIBModelController : ApiController {

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

    private Dictionary<Type, List<EntityInfo>> MyCustomBeforeSaveEntities(Dictionary<Type, List<EntityInfo>> saveMap) {     
        // your code...
    }
 }

Breeze will execute any registered validations using .NET Validation attributes during the save. Below are examples of applying validation attributes on both an entity level and a property level. Both of these validations will be executed during the save of any Customer object, and any validation errors will be returned in the SaveChanges 'fail'. promise. For now though, you will need to attach the resulting errors to the correct entity/property by inspecting the error result.

[AttributeUsage(AttributeTargets.Class)] // NEW
public class CustomerValidator : ValidationAttribute {
  public override Boolean IsValid(Object value) {
    var cust = value as Customer;
    if (cust != null && cust.CompanyName.ToLower() == "xxx") {
      ErrorMessage = "This customer is not valid!";
      return false;
    }
    return true;
  }
}

[AttributeUsage(AttributeTargets.Property)]
public class ContactNameValidator : ValidationAttribute {
  public override Boolean IsValid(Object value) {
    try {
      var val = (string)value;
      if (!string.IsNullOrEmpty(val) && val.StartsWith("xxx")) {
        ErrorMessage = "{0} should not start with 'xxx'"";
        return false;
      }
      return true;
    } catch (Exception e) {
      var x = e;
      return false;
    }
  }
}

[MetadataType(typeof(CustomerMetaData))]
[CustomerValidator]
public partial class Customer {

  [ContactNameValidator]
  public string ContactName {
    get;
    set;
  }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!