/// <summary> /// Adds a Where clause to the given query for the specified property, and a list of operators that take no values. /// If any of the specified operators are not valid, then adds validation errors and returns the same query. /// </summary> /// <typeparam name="TElement">The type of the element.</typeparam> /// <typeparam name="TValue">The type of the values.</typeparam> /// <param name="qry">The query to add the Where clause to.</param> /// <param name="propName">Property display name.</param> /// <param name="prop">Expression for the property accessor.</param> /// <param name="operators">A list of operator names or aliases.</param> /// <returns>The query with the Where clause added, or the same query if input is invalid.</returns> protected virtual IQueryable <TElement> AddClause <TElement, TValue>(IQueryable <TElement> qry, string propName, Expression <Func <TElement, TValue> > prop, ICollection <string> operators) { if (operators == null || operators.Count == 0) { return(qry); // assume no criteria, do nothing } var expressions = new List <Expression>(); foreach (string oper in operators) { Operator op = GetOperator(oper, typeof(TValue)); if (op == null) { currentErrors.AddValidationError(Messages.Operator_NotSupported, oper, GetPropertyName(propName, prop.Body)); } else { expressions.Add(op.GetPredicate(prop).Body); } } if (expressions.Count < operators.Count) { return(qry); // some operators are invalid } Expression agg = expressions.Aggregate((a, b) => Expression.Or(a, b)); return(qry.Where(Expression.Lambda <Func <TElement, bool> >(agg, prop.Parameters))); }
/// <summary> /// Adds model validation errors from the model state to the list of current errors. /// </summary> /// <param name="currentErrors">The list of current errors to add any model validation errors to.</param> /// <param name="modelState">Model state that contains model validation errors.</param> public static void AddModelErrors(this ErrorList currentErrors, ModelStateDictionary modelState) { foreach (var ms in modelState) { foreach (var err in ms.Value.Errors) { if (!string.IsNullOrEmpty(err.ErrorMessage)) { currentErrors.AddValidationError(err.ErrorMessage); } else if (err.Exception != null) { currentErrors.AddValidationError(err.Exception.Message); } } } }
/// <summary> /// Asynchronously validates if an object with the given primary key exists in the store, and reports an error if not. /// </summary> /// <typeparam name="T">The type of entity to validate.</typeparam> /// <param name="ctx">The DbContext to use.</param> /// <param name="errorList">The current error list to use for reporting errors.</param> /// <param name="param">The name of the key input parameter(s) to use in the error.</param> /// <param name="keys">The values of the primary key to validate.</param> public static async Task ValidateKeyAsync <T>(this DbContext ctx, ErrorList errorList, string param, params object[] keys) where T : class { if (keys == null || keys.Length == 0 || keys.All(k => k == null)) { return; } T entity = await ctx.Set <T>()?.FindAsync(keys); if (entity == null) { string error = keys.Length > 1 ? Messages.InvalidForeignKeys : Messages.InvalidForeignKey; errorList.AddValidationError(error, string.Join <object>(", ", keys), param, typeof(T).Name); } }
/// <summary> /// Called before client calls are sent and after service responses are returned. /// </summary> /// <param name="operationName">The name of the operation.</param> /// <param name="inputs">The objects passed to the method by the client.</param> /// <returns>The correlation state that is returned as the correlationState parameter in <see cref="AfterCall(string, object[], object, object)"/>. /// Return null if you do not intend to use correlation state.</returns> public object BeforeCall(string operationName, object[] inputs) { InstanceContextServiceScope ctxScope = OperationContext.Current.InstanceContext.Extensions.Find <InstanceContextServiceScope>(); var svcProvider = ctxScope?.GetServiceScope(null)?.ServiceProvider; ErrorList errors = svcProvider?.GetService <ErrorList>(); if (errors == null) { return(null); } foreach (object obj in inputs) { foreach (ValidationResult result in DataAnnotationValidator.GetValidationErrors(serviceProvider, obj)) { errors.AddValidationError(result.ErrorMessage); } } return(null); }