public static object GetResult(this Task task) { try { if (!task.IsCompleted) { task.Wait(); } if (task is Task <object> taskObj) { return(taskObj.Result); } var taskType = task.GetType(); if (!taskType.IsGenericType || taskType.FullName.Contains("VoidTaskResult")) { return(null); } var props = TypeProperties.Get(taskType); var fn = props.GetPublicGetter("Result"); return(fn?.Invoke(task)); } catch (TypeAccessException) { return(null); //return null for void Task's } catch (Exception ex) { throw ex.UnwrapIfSingleException(); } }
private static void InitUserFieldDefinition(Type modelType, FieldDefinition fieldDef) { if (fieldDef.PropertyInfo == null) { fieldDef.PropertyInfo = TypeProperties.Get(modelType).GetPublicProperty(fieldDef.Name); } }
public void Can_use_getter_and_setter_on_ValueTypeProps() { var typeFields = TypeProperties.Get(typeof(ValueTypeProps)); var o = (object)new ValueTypeProps { S = "foo", I = 1 }; typeFields.GetPublicSetter("S")(o, "bar"); Assert.That(typeFields.GetPublicGetter("S")(o), Is.EqualTo("bar")); typeFields.GetPublicSetter("I")(o, 2); Assert.That(typeFields.GetPublicGetter("I")(o), Is.EqualTo(2)); }
public void Can_get_result_of_Task() { var tcs = new TaskCompletionSource <string>(); var task = tcs.Task; tcs.SetResult("foo"); var fn = TypeProperties.Get(task.GetType()).GetPublicGetter("Result"); var value = fn(task); Assert.That(value, Is.EqualTo("foo")); fn = TypeProperties.Get(task.GetType()).GetPublicGetter("Result"); value = fn(task); Assert.That(value, Is.EqualTo("foo")); }
public object GetValue(object instance) { var type = instance.GetType(); if (PropertyInfo.DeclaringType?.IsAssignableFrom(type) != true) { if (instance is IDictionary d) { return(d[Name]); } var accessor = TypeProperties.Get(type).GetAccessor(Name); return(accessor?.PublicGetter(instance)); } return(this.GetValueFn?.Invoke(instance)); }
public void Can_use_TypedProperties_accessor() { var runtimeType = typeof(MyType); var typeProps = TypeProperties.Get(runtimeType); //Equivalent to: // typeProps = TypeProperties<MyType>.Instance; var instance = runtimeType.CreateInstance(); var propAccessor = typeProps.GetAccessor("LongProp"); propAccessor.PublicSetter(instance, 1L); Assert.That(propAccessor.PublicGetter(instance), Is.EqualTo(1)); typeProps.GetPublicSetter("StringProp")(instance, "foo"); var value = typeProps.GetPublicGetter("StringProp")(instance); Assert.That(value, Is.EqualTo("foo")); }
private static object PropValue(object targetValue, Type targetType, string name) { var memberFn = TypeProperties.Get(targetType).GetPublicGetter(name) ?? TypeFields.Get(targetType).GetPublicGetter(name); if (memberFn != null) { return(memberFn(targetValue)); } var indexerMethod = targetType.GetInstanceMethod("get_Item"); if (indexerMethod != null) { var fn = indexerMethod.GetInvoker(); var ret = fn(targetValue, name); return(ret ?? JsNull.Value); } throw new ArgumentException($"'{targetType.Name}' does not have a '{name}' property or field"); }
public void Can_cache_ValueTuple_field_accessors() { var typeProperties = TypeProperties.Get(typeof(RefTypeProps)); var oTuple = (object)CreateTypedTuple(); typeProperties.GetPublicSetter("S")(oTuple, "bar"); typeProperties.GetPublicSetter("I")(oTuple, 10); typeProperties.GetPublicSetter("L")(oTuple, 20L); typeProperties.GetPublicSetter("D")(oTuple, 4.4d); Assert.That(typeProperties.GetPublicGetter("S")(oTuple), Is.EqualTo("bar")); Assert.That(typeProperties.GetPublicGetter("I")(oTuple), Is.EqualTo(10)); Assert.That(typeProperties.GetPublicGetter("L")(oTuple), Is.EqualTo(20)); Assert.That(typeProperties.GetPublicGetter("D")(oTuple), Is.EqualTo(4.4)); var tuple = (RefTypeProps)oTuple; Assert.That(tuple.S, Is.EqualTo("bar")); Assert.That(tuple.I, Is.EqualTo(10)); Assert.That(tuple.L, Is.EqualTo(20)); Assert.That(tuple.D, Is.EqualTo(4.4)); }
private static object PropValue(object targetValue, Type targetType, string name) { var memberFn = TypeProperties.Get(targetType).GetPublicGetter(name) ?? TypeFields.Get(targetType).GetPublicGetter(name); if (memberFn != null) { return(memberFn(targetValue)); } var methods = targetType.GetInstanceMethods(); var indexerMethod = methods.FirstOrDefault(x => x.Name == "get_Item" && x.GetParameters().Any(p => p.ParameterType == typeof(string))) ?? methods.FirstOrDefault(x => x.Name == "get_Item" && x.GetParameters().Any(p => p.ParameterType != typeof(string))); if (indexerMethod != null) { var fn = indexerMethod.GetInvoker(); var ret = fn(targetValue, name); return(ret); } throw new ArgumentException($"'{targetType.Name}' does not have a '{name}' property or field"); }
public async Task HandleFileUploadsAsync(IRequest req, IResponse res, object dto) { if (req.Files?.Length > 0) { var requestType = dto.GetType(); // ignore unless a Request DTO Property contains [UploadTo] Attribute if (!HostContext.Metadata.GetOperation(requestType).RequestPropertyAttributes.Contains(typeof(UploadToAttribute))) { return; } var uploadFileAsync = HandleUploadFileAsync ?? throw new NotSupportedException("AppHost.HandleUploadFileAsync needs to be configured to allow file uploads in " + requestType.Name); var dtoProps = TypeProperties.Get(requestType); var uploadedPathsMap = new Dictionary <string, List <(string, IHttpFile)> >(); foreach (var file in req.Files) { var uploadedPath = await uploadFileAsync(req, file, default).ConfigAwait(); if (string.IsNullOrEmpty(uploadedPath)) { continue; } if (!uploadedPathsMap.TryGetValue(file.Name, out var uploadedPaths)) { uploadedPaths = uploadedPathsMap[file.Name] = new List <(string, IHttpFile)>(); } uploadedPaths.Add((uploadedPath, file)); } var dtoValues = new Dictionary <string, object>(); foreach (var entry in uploadedPathsMap) { var prop = dtoProps.GetPublicProperty(entry.Key); if (prop == null) { continue; } var paths = entry.Value.Map(x => x.Item1); if (prop.PropertyType == typeof(string)) { dtoValues[prop.Name] = paths[0]; } else if (prop.PropertyType.HasInterface(typeof(IEnumerable <string>))) { dtoValues[prop.Name] = paths.ConvertTo(prop.PropertyType); } else { var elType = prop.PropertyType.GetCollectionType(); if (elType != null && elType != typeof(object)) { var to = new List <object>(); foreach (var fileEntry in entry.Value) { var el = CreateFromHttpFileInfo(filePath: fileEntry.Item1, file: fileEntry.Item2, elType); to.Add(el); } dtoValues[prop.Name] = to.ConvertTo(prop.PropertyType); } else if (prop.PropertyType != typeof(object) && prop.PropertyType.IsClass) { var fileEntry = entry.Value[0]; var to = CreateFromHttpFileInfo(filePath: fileEntry.Item1, file: fileEntry.Item2, prop.PropertyType); dtoValues[prop.Name] = to; } else { throw new NotSupportedException("Cannot populated uploaded Request.Files metadata to " + prop.PropertyType.Name); } } } dtoValues.PopulateInstance(dto); } }
/// <summary> /// Converts the type of the dump. /// </summary> /// <param name="target">The target.</param> /// <returns>System.Object.</returns> internal static object ConvertDumpType(object target) { var targetType = target.GetType(); var genericKvps = targetType.GetTypeWithGenericTypeDefinitionOf(typeof(KeyValuePair <,>)); if (genericKvps != null) { var keyGetter = TypeProperties.Get(targetType).GetPublicGetter("Key"); var valueGetter = TypeProperties.Get(targetType).GetPublicGetter("Value"); return(new Dictionary <string, object> { { keyGetter(target).ConvertTo <string>(), valueGetter(target) }, }); } if (target is IEnumerable e) { //Convert IEnumerable<object> to concrete generic collection so generic args can be inferred if (e is IEnumerable <object> enumObjs) { Type elType = null; foreach (var item in enumObjs) { elType = item.GetType(); break; } if (elType != null) { targetType = typeof(List <>).MakeGenericType(elType); var genericList = (IList)targetType.CreateInstance(); foreach (var item in e) { genericList.Add(item.ConvertTo(elType)); } target = genericList; } } if (targetType.GetKeyValuePairsTypes(out var keyType, out var valueType, out var kvpType)) { var keyGetter = TypeProperties.Get(kvpType).GetPublicGetter("Key"); var valueGetter = TypeProperties.Get(kvpType).GetPublicGetter("Value"); string key1 = null, key2 = null; foreach (var kvp in e) { if (key1 == null) { key1 = keyGetter(kvp).ConvertTo <string>(); continue; } key2 = keyGetter(kvp).ConvertTo <string>(); break; } var isColumn = key1 == key2; if (isColumn) { var to = new List <Dictionary <string, object> >(); foreach (var kvp in e) { to.Add(new Dictionary <string, object> { { keyGetter(kvp).ConvertTo <string>(), valueGetter(kvp) } }); } return(to); } return(target.ToObjectDictionary()); } } return(target); }
private static async Task RequestFilterAsync(IRequest req, IResponse res, object requestDto, bool treatInfoAndWarningsAsErrors) { var requestType = requestDto.GetType(); await Validators.AssertTypeValidatorsAsync(req, requestDto, requestType); var validator = ValidatorCache.GetValidator(req, requestType); if (validator == null) { return; } using (validator as IDisposable) { if (validator is IHasTypeValidators hasTypeValidators && hasTypeValidators.TypeValidators.Count > 0) { foreach (var scriptValidator in hasTypeValidators.TypeValidators) { await scriptValidator.ThrowIfNotValidAsync(requestDto, req); } } try { if (req.Verb == HttpMethods.Patch) { // Ignore property rules for AutoCrud Patch operations with default values that aren't reset (which are ignored) if (validator is IServiceStackValidator ssValidator && requestDto is ICrud && requestType.IsOrHasGenericInterfaceTypeOf(typeof(IPatchDb <>))) { var typeProperties = TypeProperties.Get(requestType); var propsWithDefaultValues = new HashSet <string>(); var resetFields = GetResetFields(req.GetParam(Keywords.reset))?.ToSet(StringComparer.OrdinalIgnoreCase) ?? TypeConstants <string> .EmptyHashSet; foreach (var entry in typeProperties.PropertyMap) { if (entry.Value.PublicGetter == null || resetFields.Contains(entry.Key)) { continue; } var defaultValue = entry.Value.PropertyInfo.PropertyType.GetDefaultValue(); var propValue = entry.Value.PublicGetter(requestDto); if (propValue == null || propValue.Equals(defaultValue)) { propsWithDefaultValues.Add(entry.Key); } } if (propsWithDefaultValues.Count > 0) { ssValidator.RemovePropertyRules(rule => propsWithDefaultValues.Contains(rule.PropertyName)); } } } var validationResult = await validator.ValidateAsync(req, requestDto); if (treatInfoAndWarningsAsErrors && validationResult.IsValid) { return; } if (!treatInfoAndWarningsAsErrors && (validationResult.IsValid || validationResult.Errors.All(v => v.Severity != Severity.Error))) { return; } var errorResponse = await HostContext.RaiseServiceException(req, requestDto, validationResult.ToException()) ?? DtoUtils.CreateErrorResponse(requestDto, validationResult.ToErrorResult()); var autoBatchIndex = req.GetItem(Keywords.AutoBatchIndex)?.ToString(); if (autoBatchIndex != null) { var responseStatus = errorResponse.GetResponseStatus(); if (responseStatus != null) { if (responseStatus.Meta == null) { responseStatus.Meta = new Dictionary <string, string>(); } responseStatus.Meta[Keywords.AutoBatchIndex] = autoBatchIndex; } } var validationFeature = HostContext.GetPlugin <ValidationFeature>(); if (validationFeature?.ErrorResponseFilter != null) { errorResponse = validationFeature.ErrorResponseFilter(req, validationResult, errorResponse); } await res.WriteToResponse(req, errorResponse); } catch (Exception ex) { var validationEx = ex.UnwrapIfSingleException(); var errorResponse = await HostContext.RaiseServiceException(req, requestDto, validationEx) ?? DtoUtils.CreateErrorResponse(requestDto, validationEx); await res.WriteToResponse(req, errorResponse); } } }
private object GetValue(object targetValue, TemplateScopeContext scope) { if (targetValue == null || targetValue == JsNull.Value) { return(JsNull.Value); } var targetType = targetValue.GetType(); try { object propValue(string name) { var memberFn = TypeProperties.Get(targetType).GetPublicGetter(name) ?? TypeFields.Get(targetType).GetPublicGetter(name); if (memberFn != null) { return(memberFn(targetValue)); } var indexerMethod = targetType.GetInstanceMethod("get_Item"); if (indexerMethod != null) { var fn = indexerMethod.GetInvoker(); var ret = fn(targetValue, name); return(ret ?? JsNull.Value); } throw new ArgumentException($"'{targetType.Name}' does not have a '{name}' property or field"); } if (!Computed) { if (Property is JsIdentifier identifier) { var ret = propValue(identifier.NameString); // Don't emit member expression on null KeyValuePair if (ret == null && targetType.Name == "KeyValuePair`2") { return(JsNull.Value); } return(ret); } } else { var indexValue = Property.Evaluate(scope); if (indexValue == null) { return(JsNull.Value); } if (targetType.IsArray) { var array = (Array)targetValue; if (indexValue is long l) { return(array.GetValue(l)); } var intValue = indexValue.ConvertTo <int>(); return(array.GetValue(intValue)); } if (targetValue is IDictionary dict) { var ret = dict[indexValue]; return(ret ?? JsNull.Value); } if (indexValue is string propName) { return(propValue(propName)); } if (targetValue is IList list) { var intValue = indexValue.ConvertTo <int>(); return(list[intValue]); } if (targetValue is IEnumerable e) { var intValue = indexValue.ConvertTo <int>(); var i = 0; foreach (var item in e) { if (i++ == intValue) { return(item); } } return(null); } if (DynamicNumber.IsNumber(indexValue.GetType())) { var indexerMethod = targetType.GetInstanceMethod("get_Item"); if (indexerMethod != null) { var fn = indexerMethod.GetInvoker(); var ret = fn(targetValue, indexValue); return(ret ?? JsNull.Value); } } } } catch (KeyNotFoundException) { return(JsNull.Value); } catch (Exception ex) { var exResult = scope.PageResult.Format.OnExpressionException(scope.PageResult, ex); if (exResult != null) { return(exResult); } var expr = ToRawString(); throw new BindingExpressionException($"Could not evaluate expression '{expr}'", null, expr, ex); } throw new NotSupportedException($"'{targetValue.GetType()}' does not support access by '{Property}'"); }
internal static IDbCommand SetParameters(this IDbCommand dbCmd, Type type, object anonType, bool excludeDefaults, ref string sql) { if (anonType == null) { return(dbCmd); } dbCmd.Parameters.Clear(); var modelDef = type.GetModelDefinition(); var dialectProvider = dbCmd.GetDialectProvider(); var fieldMap = type.IsUserType() //Ensure T != Scalar<int>() ? dialectProvider.GetFieldDefinitionMap(modelDef) : null; var sqlCopy = sql; //C# doesn't allow changing ref params in lambda's Dictionary <string, PropertyAccessor> anonTypeProps = null; var paramIndex = 0; anonType.ToObjectDictionary().ForEachParam(modelDef, excludeDefaults, (propName, columnName, value) => { var propType = value?.GetType() ?? ((anonTypeProps ??= TypeProperties.Get(anonType.GetType()).PropertyMap) .TryGetValue(propName, out var pType) ? pType.PropertyInfo.PropertyType : typeof(object)); var inValues = GetMultiValues(value); if (inValues != null) { var sb = StringBuilderCache.Allocate(); foreach (var item in inValues) { var p = dbCmd.CreateParameter(); p.ParameterName = "v" + paramIndex++; if (sb.Length > 0) { sb.Append(','); } sb.Append(dialectProvider.ParamString + p.ParameterName); p.Direction = ParameterDirection.Input; dialectProvider.InitDbParam(p, item.GetType()); dialectProvider.SetParamValue(p, item, item.GetType()); dbCmd.Parameters.Add(p); } var sqlIn = StringBuilderCache.ReturnAndFree(sb); if (string.IsNullOrEmpty(sqlIn)) { sqlIn = "NULL"; } sqlCopy = sqlCopy?.Replace(dialectProvider.ParamString + propName, sqlIn); if (dialectProvider.ParamString != "@") { sqlCopy = sqlCopy?.Replace("@" + propName, sqlIn); } } else { var p = dbCmd.CreateParameter(); p.ParameterName = propName; p.Direction = ParameterDirection.Input; dialectProvider.InitDbParam(p, propType); FieldDefinition fieldDef = null; fieldMap?.TryGetValue(columnName, out fieldDef); dialectProvider.SetParamValue(p, value, propType, fieldDef); dbCmd.Parameters.Add(p); } });
protected async Task <Message> ExecuteMessage(Message message, RequestAttributes requestAttributes, IRequest httpReq, IResponse httpRes) { var soapFeature = requestAttributes.ToSoapFeature(); appHost.AssertFeatures(soapFeature); if (httpReq == null) { httpReq = HostContext.GetCurrentRequest(); } if (httpRes == null && httpReq != null) { httpRes = httpReq.Response; } if (httpReq == null) { throw new ArgumentNullException(nameof(httpReq)); } if (httpRes == null) { throw new ArgumentNullException(nameof(httpRes)); } httpReq.UseBufferedStream = true; var requestMsg = message ?? GetRequestMessageFromStream(httpReq.InputStream); var soapAction = httpReq.GetHeader(HttpHeaders.SOAPAction) ?? GetAction(requestMsg); if (soapAction != null) { httpReq.OperationName = soapAction.Trim('"'); } if (HostContext.ApplyCustomHandlerRequestFilters(httpReq, httpRes)) { return(PrepareEmptyResponse(message, httpReq)); } string requestXml = GetRequestXml(requestMsg); var requestType = GetRequestType(requestMsg, requestXml); httpReq.OperationName = requestType.GetOperationName(); if (!HostContext.Metadata.CanAccess(requestAttributes, soapFeature.ToFormat(), requestType.GetOperationName())) { throw HostContext.UnauthorizedAccess(requestAttributes); } try { var useXmlSerializerRequest = requestType.HasAttribute <XmlSerializerFormatAttribute>(); var request = appHost.ApplyRequestConvertersAsync(httpReq, useXmlSerializerRequest ? XmlSerializableSerializer.Instance.DeserializeFromString(requestXml, requestType) : Serialization.DataContractSerializer.Instance.DeserializeFromString(requestXml, requestType) ).Result; httpReq.Dto = request; if (request is IRequiresSoapMessage requiresSoapMessage) { requiresSoapMessage.Message = requestMsg; } httpReq.SetItem(Keywords.SoapMessage, requestMsg); httpRes.ContentType = GetSoapContentType(httpReq.ContentType); var hasRequestFilters = HostContext.AppHost.GlobalRequestFiltersArray.Length > 0 || HostContext.AppHost.GlobalRequestFiltersAsyncArray.Length > 0 || FilterAttributeCache.GetRequestFilterAttributes(request.GetType()).Any(); if (hasRequestFilters) { HostContext.ApplyRequestFiltersAsync(httpReq, httpRes, request).Wait(); if (httpRes.IsClosed) { return(EmptyResponse(requestMsg, requestType)); } } httpReq.RequestAttributes |= requestAttributes; var response = await GetResponseAsync(httpReq, request); response = appHost.ApplyResponseConvertersAsync(httpReq, response).Result; appHost.ApplyResponseFiltersAsync(httpReq, httpRes, response).Wait(); if (httpRes.IsClosed) { return(EmptyResponse(requestMsg, requestType)); } var httpResult = response as IHttpResult; if (httpResult != null) { response = httpResult.Response; } var noMsgAction = requestMsg.Headers.Action == null; var responseMsg = CreateResponseMessage(response, requestMsg.Version, requestType, noMsgAction); if (httpResult != null) { SetErrorStatusIfAny(httpReq.Response, responseMsg, httpResult.Status); } return(responseMsg); } catch (Exception ex) { try { if (httpReq.Dto != null) { HostContext.RaiseServiceException(httpReq, httpReq.Dto, ex).Wait(); } else { HostContext.RaiseUncaughtException(httpReq, httpRes, httpReq.OperationName, ex).Wait(); } throw new SerializationException($"Error trying to deserialize requestType: {requestType}, xml body: {requestXml}", ex); } catch (Exception useEx) { var responseType = HostContext.Metadata.GetOperation(requestType).ResponseType ?? typeof(ErrorResponse); var responseStatus = useEx.ToResponseStatus(); var response = responseType.CreateInstance(); var setter = TypeProperties.Get(responseType).GetPublicSetter(nameof(IHasResponseStatus.ResponseStatus)); setter(response, responseStatus); var noMsgAction = requestMsg.Headers.Action == null; var responseMsg = CreateResponseMessage(response, requestMsg.Version, requestType, noMsgAction); SetErrorStatusIfAny(httpReq.Response, responseMsg, useEx.ToStatusCode()); return(responseMsg); } } }
public async Task Any(ModifyValidationRules request) { var appHost = HostContext.AssertAppHost(); var feature = appHost.AssertPlugin <ValidationFeature>(); await RequestUtils.AssertAccessRoleAsync(base.Request, accessRole : feature.AccessRole, authSecret : request.AuthSecret); var utcNow = DateTime.UtcNow; var userName = (await base.GetSessionAsync()).GetUserAuthName(); var rules = request.SaveRules; if (!rules.IsEmpty()) { foreach (var rule in rules) { if (rule.Type == null) { throw new ArgumentNullException(nameof(rule.Type)); } var existingType = appHost.Metadata.FindDtoType(rule.Type); if (existingType == null) { throw new ArgumentException(@$ "{rule.Type} does not exist", nameof(rule.Type)); } if (rule.Validator == "") { rule.Validator = null; } if (rule.Condition == "") { rule.Condition = null; } if (rule.Field == "") { rule.Field = null; } if (rule.ErrorCode == "") { rule.ErrorCode = null; } if (rule.Message == "") { rule.Message = null; } if (rule.Notes == "") { rule.Notes = null; } if (rule.Field != null && TypeProperties.Get(existingType).GetAccessor(rule.Field) == null) { throw new ArgumentException(@$ "{rule.Field} does not exist on {rule.Type}", nameof(rule.Field)); } if (rule.Validator != null) { object validator; try { validator = appHost.EvalExpression(rule.Validator); if (validator == null) { throw new ArgumentException(@$ "Validator does not exist", nameof(rule.Validator)); } } catch (Exception e) { throw new ArgumentException(@$ "Invalid Validator: " + e.Message, nameof(rule.Validator)); } var validators = (validator as List <object>) ?? TypeConstants.EmptyObjectList; var firstValidator = validator is IPropertyValidator pv ? pv : validator is ITypeValidator tv ? tv : validators?.FirstOrDefault() ?? validator; if (rule.Field != null && !(firstValidator is IPropertyValidator && validators.All(v => v is IPropertyValidator))) { throw new ArgumentException(@$ "{nameof(IPropertyValidator)} is expected but was {(validators?.FirstOrDefault(v => !(v is IPropertyValidator)) ?? firstValidator).GetType().Name}", nameof(rule.Validator)); } if (rule.Field == null && !(firstValidator is ITypeValidator && validators.All(v => v is ITypeValidator))) { throw new ArgumentException(@$ "{nameof(ITypeValidator)} is expected but was {(validators?.FirstOrDefault(v => !(v is IPropertyValidator)) ?? firstValidator).GetType().Name}", nameof(rule.Validator)); } if (rule.Condition != null) { throw new ArgumentException(@$ "Only {nameof(rule.Validator)} or {nameof(rule.Condition)} can be specified, not both", nameof(rule.Condition)); } } else { if (rule.Condition == null) { throw new ArgumentNullException(nameof(rule.Validator), @$ "{nameof(rule.Validator)} or {nameof(rule.Condition)} is required"); } try { var ast = Validators.ParseCondition(appHost.ScriptContext, rule.Condition); await ast.Init().ConfigAwait(); } catch (Exception e) { var useEx = e is ScriptException se ? se.InnerException ?? e : e; throw new ArgumentException(useEx.Message, nameof(rule.Condition)); } } if (rule.CreatedBy == null) { rule.CreatedBy = userName; rule.CreatedDate = utcNow; } rule.ModifiedBy = userName; rule.ModifiedDate = utcNow; } await ValidationSource.SaveValidationRulesAsync(rules).ConfigAwait(); } if (!request.SuspendRuleIds.IsEmpty()) { var suspendRules = await ValidationSource.GetValidateRulesByIdsAsync(request.SuspendRuleIds).ConfigAwait(); foreach (var suspendRule in suspendRules) { suspendRule.SuspendedBy = userName; suspendRule.SuspendedDate = utcNow; } await ValidationSource.SaveValidationRulesAsync(suspendRules).ConfigAwait(); } if (!request.UnsuspendRuleIds.IsEmpty()) { var unsuspendRules = await ValidationSource.GetValidateRulesByIdsAsync(request.UnsuspendRuleIds).ConfigAwait(); foreach (var unsuspendRule in unsuspendRules) { unsuspendRule.SuspendedBy = null; unsuspendRule.SuspendedDate = null; } await ValidationSource.SaveValidationRulesAsync(unsuspendRules).ConfigAwait(); } if (!request.DeleteRuleIds.IsEmpty()) { await ValidationSource.DeleteValidationRulesAsync(request.DeleteRuleIds.ToArray()).ConfigAwait(); } if (request.ClearCache.GetValueOrDefault()) { await ValidationSource.ClearCacheAsync().ConfigAwait(); } }
private static bool HasCircularReferences(object value, Stack <object> parentValues) { var type = value?.GetType(); if (type == null || !type.IsClass || value is string) { return(false); } if (parentValues == null) { parentValues = new Stack <object>(); parentValues.Push(value); } bool CheckValue(object key) { if (parentValues.Contains(key)) { return(true); } parentValues.Push(key); if (HasCircularReferences(key, parentValues)) { return(true); } parentValues.Pop(); return(false); } if (value is IEnumerable valueEnumerable) { foreach (var item in valueEnumerable) { if (item == null) { continue; } var itemType = item.GetType(); if (itemType.IsGenericType && itemType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>)) { var props = TypeProperties.Get(itemType); var key = props.GetPublicGetter("Key")(item); if (CheckValue(key)) { return(true); } var val = props.GetPublicGetter("Value")(item); if (CheckValue(val)) { return(true); } } if (CheckValue(item)) { return(true); } } } else { var props = type.GetSerializableProperties(); foreach (var pi in props) { if (pi.GetIndexParameters().Length > 0) { continue; } var mi = pi.GetGetMethod(nonPublic: false); var pValue = mi != null?mi.Invoke(value, null) : null; if (pValue == null) { continue; } if (CheckValue(pValue)) { return(true); } } } return(false); }