protected override IList <JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { var members = GetSerializableMembers(type).Where(x => x.GetCustomAttribute <IgnoreAttribute>() == null); var properties = new JsonPropertyCollection(type); foreach (var member in members) { var property = CreateProperty(member, memberSerialization); if (EntityType.IsAssignableFrom(property.PropertyType) || (property.PropertyType != typeof(string) && EnumerableType.IsAssignableFrom(property.PropertyType))) { property.ShouldSerialize = (x) => { if (!NHibernateUtil.IsPropertyInitialized(x, member.Name)) { return(false); } return(NHibernateUtil.IsInitialized(x.GetMemberValue(member.Name))); }; } properties.AddProperty(property); } return(properties.OrderBy(p => p.Order ?? -1).ToList()); }
protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) { List members = GetSerializableMembers(type); if (members == null) { throw new JsonSerializationException("Null collection of seralizable members returned."); } var properties = new JsonPropertyCollection(type); foreach (MemberInfo member in members) { JsonProperty property = CreateProperty(member, memberSerialization); if (property != null) { properties.AddProperty(property); } } IList orderedProperties = properties.OrderBy(p => p.Order + (MaxPropertiesPerContract * GetTypeDepth(p.DeclaringType)) ?? -1).ToList(); return(orderedProperties); }
protected override IList <JsonProperty> CreateConstructorParameters(ConstructorInfo constructor, JsonPropertyCollection memberProperties) { var constructorParameters = constructor.GetParameters(); JsonPropertyCollection parameterCollection = new JsonPropertyCollection(constructor.DeclaringType); foreach (ParameterInfo parameterInfo in constructorParameters) { JsonProperty matchingMemberProperty = (parameterInfo.Name != null) ? memberProperties.GetClosestMatchProperty(parameterInfo.Name) : null; // Constructor type must be assignable from property type. // Note that this is the only difference between this method and the method it overrides in DefaultContractResolver. // In DefaultContractResolver, the types must match exactly. if (matchingMemberProperty != null && !parameterInfo.ParameterType.IsAssignableFrom(matchingMemberProperty.PropertyType)) { matchingMemberProperty = null; } if (matchingMemberProperty != null || parameterInfo.Name != null) { JsonProperty property = CreatePropertyFromConstructorParameterWithConstructorInfo(matchingMemberProperty, parameterInfo, constructor); if (property != null) { parameterCollection.AddProperty(property); } } } return(parameterCollection); }
/// <inheritdoc /> protected override IList <JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { if (typeof(INHibernateProxy).IsAssignableFrom(type)) { return(new List <JsonProperty>()); // They will be copied from the base type } var members = GetSerializableMembers(type); if (members == null) { throw new JsonSerializationException("Null collection of serializable members returned."); } var propertyMembers = new Dictionary <JsonProperty, MemberInfo>(members.Count); var modelConfiguration = _breezeConfigurator.GetModelConfiguration(type); var metadata = GetTypeMetadata(type); var properties = new JsonPropertyCollection(type); foreach (var member in members) { var property = CreateProperty(member, memberSerialization, metadata); propertyMembers.Add(property, member); properties.AddProperty(property); } foreach (var syntheticMember in modelConfiguration.SyntheticMembers.Values.Where(o => o.Added)) { properties.AddProperty(CreateSyntheticProperty(syntheticMember)); } if (metadata != null) { foreach (var syntheticProperty in metadata.SyntheticForeignKeyProperties.Values) { properties.AddProperty(CreateSyntheticForeignKeyProperty( type, syntheticProperty, modelConfiguration.GetSyntheticMember(syntheticProperty.Name), modelConfiguration.GetMember(syntheticProperty.AssociationPropertyName))); } } ApplyModelConfiguration(type, properties, modelConfiguration, metadata, propertyMembers); return(properties.OrderBy(p => p.Order ?? -1).ToList()); }
/// <summary> /// Creates properties for the given <see cref="JsonContract"/>. /// </summary> /// <param name="type">The type to create properties for.</param> /// /// <param name="memberSerialization">The member serialization mode for the type.</param> /// <returns>Properties for the given <see cref="JsonContract"/>.</returns> protected override IList <JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { var members = GetSerializableMembers(type); if (members == null) { throw new JsonSerializationException("Null collection of seralizable members returned."); } var properties = new JsonPropertyCollection(type); var modelConfiguration = _breezeConfigurator.GetModelConfiguration(type); foreach (var member in members) { var property = CreateProperty(type, member, memberSerialization, modelConfiguration); if (property != null) { var nameTable = DefaultContractResolverStateNameTableField.GetValue(this); // nametable is not thread-safe for multiple writers lock (nameTable) { property.PropertyName = (string)PropertyNameTableAddMethod .Invoke(nameTable, new object[] { property.PropertyName }); } properties.AddProperty(property); } } var syntheticPoperties = _getMetadataFunc(type).GetSyntheticProperties(); if (syntheticPoperties != null && syntheticPoperties.Any()) { foreach (var syntheticProp in syntheticPoperties) { var propertyName = ResolvePropertyName(syntheticProp.Name); // Skip manually added syntetic properties if (!properties.Any(x => x.PropertyName == propertyName)) { properties.Add(new JsonProperty { Readable = true, Writable = true, PropertyName = propertyName, PropertyType = syntheticProp.PkType.ReturnedClass, ValueProvider = new NHSyntheticPropertyValueProvider(syntheticProp) }); } } } IList <JsonProperty> orderedProperties = properties.OrderBy(p => p.Order ?? -1).ToList(); ApplySerializationRules(type, orderedProperties, memberSerialization); return(orderedProperties); }
protected override IList <JsonProperty> CreateConstructorParameters(ConstructorInfo constructor, JsonPropertyCollection memberProperties) { var constructorParameters = constructor.GetParameters(); JsonPropertyCollection parameterCollection = new JsonPropertyCollection(constructor.DeclaringType); foreach (ParameterInfo parameterInfo in constructorParameters) { var matchingMemberProperty = (parameterInfo.Name != null) ? memberProperties.GetClosestMatchProperty(parameterInfo.Name) : null; // Constructor type must be assignable from property type. // Note that this is the only difference between this method and the method it overrides in DefaultContractResolver. // In DefaultContractResolver, the types must match exactly. if (matchingMemberProperty != null) { var memberType = matchingMemberProperty.PropertyType; var memberTypeIsGeneric = memberType.IsGenericType; var memberGenericArguments = memberType.GetGenericArguments(); var parameterTypeIsArray = parameterInfo.ParameterType.IsArray; var parameterElementType = parameterInfo.ParameterType.GetElementType(); if (parameterTypeIsArray && memberTypeIsGeneric && memberGenericArguments.Length == 1 && memberType.IsAssignableTo(typeof(IEnumerable <>).MakeGenericType(parameterElementType))) { // NO-OP - this allows for the constructor parameter to be a "params" array while still using a collection property as the source. } else if (memberType.IsAssignableTo(parameterInfo.ParameterType)) { // NO-OP - vanilla assignable type to constructor check. } else { // no way to do this so null out and the let the next step error with a clean message. matchingMemberProperty = null; } } if (matchingMemberProperty != null || parameterInfo.Name != null) { var property = this.CreatePropertyFromConstructorParameterWithConstructorInfo(matchingMemberProperty, parameterInfo, constructor); if (property != null) { parameterCollection.AddProperty(property); } } } return(parameterCollection); }
protected override IList <JsonProperty> CreateProperties(Type type, MemberSerialization serialization) { var properties = new JsonPropertyCollection(type); foreach (JsonProperty property in GetSerializableMembers(type).Select(m => CreateProperty(m, serialization)).WhereNotNull()) { properties.AddProperty(property); } return(properties .OrderBy(p => p.Order ?? -1) .ThenBy(IsPropertyCollection) .ThenBy(GetPropertyTypeDepth) .ThenBy(p => p.PropertyName) .ToList()); }
protected override IList <JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { if (!type.Implements <IDwarf>()) { return(base.CreateProperties(type, memberSerialization)); } var members = GetSerializableMembers(type); if (members == null) { throw new JsonSerializationException("Null collection of seralizable members returned."); } var properties = new JsonPropertyCollection(type); foreach (var member in members) { var property = CreateProperty(member, memberSerialization); if (member.GetCustomAttributes <IgnoreDataMemberAttribute>().Any()) { continue; } if (member.GetCustomAttributes <JsonIdOnlyAttribute>().Any()) { property.PropertyName += "Id"; property.Converter = jsonIdOnlyConverter; } if (property != null) { properties.AddProperty(property); } } var orderedProperties = properties.OrderBy(p => p.Order ?? -1).ToList(); orderedProperties.Move(orderedProperties.FirstOrDefault(x => x.PropertyName == "id"), 0); orderedProperties.Move(orderedProperties.FirstOrDefault(x => x.PropertyName == "isSaved"), 1); return(orderedProperties); }
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { List<MemberInfo> members = this.GetSerializableMembers(type); if (members == null) { throw new JsonSerializationException("Null collection of seralizable members returned."); } JsonPropertyCollection properties = new JsonPropertyCollection(type); foreach (MemberInfo member in members) { JsonProperty property = this.CreateProperty(member, memberSerialization); if (property != null) { properties.AddProperty(property); } } // IList<JsonProperty> orderedProperties = properties.OrderBy(p => p.Order ?? -1).ToList(); return properties; }
internal static bool ResolveEntityProperties(IList <JsonProperty> jsonProperties, Type entityType, EntityTypeInfo entityTypeInfo, EntityService entityService, DefaultContractResolver resolver, Func <PropertyInfo, JsonProperty> createPropertyFunc) { if (entityService.ContainsEntityType(entityType)) { if (jsonProperties.Any(jp => jp.PropertyName == Defaults.MetadataPropertyName && jp.UnderlyingName == Defaults.DummyMetadataPropertyInfo.Name)) { return(false); //if we ever find the metadata property there, assume it has been resolved. } var _properties = new JsonPropertyCollection(entityType); var isComplex = entityType.IsComplex(); var propertiesToIgnore = entityTypeInfo.PropertiesToIgnore.ToArray(); foreach (var jsonProp in jsonProperties) { if (isComplex) { jsonProp.NullValueHandling = NullValueHandling.Include; //we need null values for complex types jsonProp.DefaultValueHandling = DefaultValueHandling.Include; //we need all properties serialized } if (!jsonProp.Ignored && propertiesToIgnore.Any(np => np.Name == jsonProp.UnderlyingName)) { jsonProp.Ignored = true; } _properties.Add(jsonProp); } lock (entityTypeInfo) { //check for complextypes var complexTypedProperties = entityTypeInfo.ComplexTypedProperties; var complexJsonProperties = new List <JsonProperty>(); if (complexTypedProperties?.Count > 0) { //filter to complexproperties var filteredJsonProperties = _properties? .Select(p => new { JsonProperty = p, PropertyInfo = complexTypedProperties.Where(pi => pi.Name == p.UnderlyingName) .FirstOrDefault() }) .Where(np => np.PropertyInfo != null) .ToDictionary(np => np.JsonProperty, np => np.PropertyInfo); Func <Type, IList <JsonProperty> > getResolvedPropertiesFunc = t => { var contract = resolver.ResolveContract(t) as JsonObjectContract; if (contract.Properties?.Count > 0) { ResolveEntityProperties (contract.Properties, t, entityService.GetEntityTypeInfo(t), entityService, resolver, createPropertyFunc); } return(contract.Properties); }; //generate new properties with new names for the complex types foreach (var complexTypedJsonProp in filteredJsonProperties) { //get the complexTypedProperty's own jsonproperties //include derived classes var derivedTypes = entityService .GetDerivedEntityTypes(complexTypedJsonProp.Key.PropertyType)? .Where(t => t.IsComplex()).ToList(); if (derivedTypes == null || derivedTypes.Count == 0) { entityService.AddEntityType(complexTypedJsonProp.Key.PropertyType); derivedTypes = new List <Type> { complexTypedJsonProp.Key.PropertyType }; } var childProperties = derivedTypes .SelectMany(dt => getResolvedPropertiesFunc(dt)?.Where (p => /*!p.Ignored &&*/ p.PropertyName != Defaults.MetadataPropertyName) ?? new JsonProperty[0], (dt, property) => new { DerivedType = dt, Property = property }) .Where(jp => jp.Property != null) .GroupBy(jp => jp.Property.PropertyName) .Select(jpg => jpg.FirstOrDefault()) .ToList(); foreach (var childProp in childProperties) { //add the child to this type's properties try { var newChildProp = GetComplexTypedPropertyChild (childProp.DerivedType, complexTypedJsonProp.Key, complexTypedJsonProp.Value, childProp.Property); _properties.AddProperty(newChildProp); complexJsonProperties.Add(newChildProp); } catch (JsonSerializationException e) { //for some reason member already exists and is duplicate } } //ignore all complex typed properties complexTypedJsonProp.Key.Ignored = true; } } var nextIdx = -1; //clear and re-add these properties jsonProperties.Clear(); var orderedProperties = _properties.OrderBy(p => p.Order ?? nextIdx++); foreach (var prop in orderedProperties) { jsonProperties.Add(prop); } //create metadata property and add it last var metadataJsonProperty = createPropertyFunc(Defaults.DummyMetadataPropertyInfo); metadataJsonProperty.PropertyName = Defaults.MetadataPropertyName; metadataJsonProperty.ValueProvider = new MetadataValueProvider(entityType, complexJsonProperties); metadataJsonProperty.ShouldSerialize = instance => { return(!(metadataJsonProperty.ValueProvider as MetadataValueProvider) .BuildMetadata(instance).IsEmpty()); }; metadataJsonProperty.Order = int.MaxValue; //try to make it the last serialized jsonProperties.Add(metadataJsonProperty); //assign and resolve these properties entityTypeInfo.JsonProperties = new List <JsonProperty>(jsonProperties); return(true); } } return(false); }
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { var objectType = type.GetBaseObjectType() ?? type; if (!_propertyies.ContainsKey(objectType)) { var props = base.CreateProperties(objectType, memberSerialization); if (!objectType.IsBaseObject()) { _propertyies.Add(objectType, props); return _propertyies[objectType]; } if (_config.TypeEntity == objectType) { var resProps = new List<JsonProperty>(); foreach (var prop in props) { if (prop.PropertyType.IsBaseObject() || prop.PropertyType.IsBaseCollection()) { if (_editors.All(x => x.PropertyName != prop.PropertyName)) continue; } resProps.Add(prop); } _propertyies.Add(objectType, resProps); } else { var config = _uiFasade.GetViewModelConfig(objectType); if (config == null) return props; if (objectType.IsDefined(typeof(ComplexTypeAttribute), false)) return props; var editor = _editors.FirstOrDefault(x => x.EditorType == objectType); if (editor == null) return props; if (editor.EditorTemplate == "EasyCollection") { var typeEasyCollection = editor.ViewModelConfig.TypeEntity; if (!_propertyies.ContainsKey(typeEasyCollection)) { var properties = new JsonPropertyCollection(typeEasyCollection); properties.AddProperty(CreateProperty(typeEasyCollection.GetProperty("ID"), memberSerialization)); if (editor.ViewModelConfig.LookupProperty != "ID") properties.AddProperty(CreateProperty( typeEasyCollection.GetProperty(editor.ViewModelConfig.LookupProperty), memberSerialization)); _propertyies.Add(typeEasyCollection, properties); } } if (editor.Relationship == Relationship.OneToMany) return props; var sysColumns = _uiFasade.GetEditors(objectType) .Where( c => c.IsSystemPropery && (c.PropertyName != "RowVersion" && c.PropertyName != "Hidden" && c.PropertyName != "SortOrder")).ToList(); props = props.Where( p => p.PropertyName == config.LookupProperty || sysColumns.Any(x => x.PropertyName == p.PropertyName && x.IsSystemPropery)).ToList(); _propertyies.Add(objectType, props); } } return _propertyies[objectType]; }
protected virtual IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { List<MemberInfo> serializableMembers = this.GetSerializableMembers(type); if (serializableMembers == null) throw new JsonSerializationException("Null collection of seralizable members returned."); JsonPropertyCollection propertyCollection = new JsonPropertyCollection(type); foreach (MemberInfo member in serializableMembers) { JsonProperty property = this.CreateProperty(member, memberSerialization); if (property != null) propertyCollection.AddProperty(property); } return (IList<JsonProperty>) Enumerable.ToList<JsonProperty>((IEnumerable<JsonProperty>) Enumerable.OrderBy<JsonProperty, int>((IEnumerable<JsonProperty>) propertyCollection, (Func<JsonProperty, int>) (p => p.Order ?? -1))); }
protected virtual IList<JsonProperty> CreateConstructorParameters(ConstructorInfo constructor, JsonPropertyCollection memberProperties) { ParameterInfo[] parameters = constructor.GetParameters(); JsonPropertyCollection propertyCollection = new JsonPropertyCollection(constructor.DeclaringType); foreach (ParameterInfo parameterInfo in parameters) { JsonProperty matchingMemberProperty = parameterInfo.Name != null ? memberProperties.GetClosestMatchProperty(parameterInfo.Name) : (JsonProperty) null; if (matchingMemberProperty != null && matchingMemberProperty.PropertyType != parameterInfo.ParameterType) matchingMemberProperty = (JsonProperty) null; JsonProperty constructorParameter = this.CreatePropertyFromConstructorParameter(matchingMemberProperty, parameterInfo); if (constructorParameter != null) propertyCollection.AddProperty(constructorParameter); } return (IList<JsonProperty>) propertyCollection; }
protected override IList <JsonProperty> CreateConstructorParameters( ConstructorInfo constructor, JsonPropertyCollection memberProperties) { var constructorParameters = constructor.GetParameters(); var result = new JsonPropertyCollection(constructor.DeclaringType); foreach (var parameterInfo in constructorParameters) { var matchingMemberProperty = (parameterInfo.Name != null) ? memberProperties.GetClosestMatchProperty(parameterInfo.Name) : null; // Constructor type must be assignable from property type. // Note that this is the only difference between this method and the method it overrides in DefaultContractResolver. // In DefaultContractResolver, the types must match exactly. if (matchingMemberProperty != null) { var memberType = matchingMemberProperty.PropertyType; var memberTypeIsGeneric = memberType.IsGenericType; var memberGenericArguments = memberType.GenericTypeArguments; var parameterTypeIsArray = parameterInfo.ParameterType.IsArray; var parameterElementType = parameterInfo.ParameterType.GetElementType(); if (parameterTypeIsArray && memberTypeIsGeneric && memberGenericArguments.Length == 1 && memberType.IsAssignableTo(typeof(IEnumerable <>).MakeGenericType(parameterElementType))) { // NO-OP // this allows for the constructor parameter to be a "params" array while still using a collection property as the source. } else if (memberType.IsAssignableTo(parameterInfo.ParameterType)) { // NO-OP // The property type and the constructor parameter type are equal. // OR // The property type is assignable to the constructor parameter type. // In this case, the constructor is taking a less derived type and converting it // to a more derived type before assigning to the property // (e.g. constructor takes IEnumerable<string>, but property is an IReadOnlyCollection<string> // because the constructor calls .ToList() before assigning to the property). } else if (parameterInfo.ParameterType.IsAssignableTo(memberType)) { // NO-OP // The constructor parameter type is assignable to the property type. // In this case, the constructor is taking a more derived type and assigning // it to the property that is less derived. // (e.g. constructor takes IReadOnlyCollection<string> and assigns it to a property // of type IEnumerable<string>). } else { // no way to do this so null out and the let the next step error with a clean message. matchingMemberProperty = null; } } if (matchingMemberProperty != null || parameterInfo.Name != null) { var property = this.CreatePropertyFromConstructorParameterWithConstructorInfo(matchingMemberProperty, parameterInfo, constructor); if (property != null) { result.AddProperty(property); } } } return(result); }
protected override IList<JsonProperty> CreateProperties (Type type, MemberSerialization serialization) { var properties = new JsonPropertyCollection(type); foreach (JsonProperty property in GetSerializableMembers(type).Select(m => CreateProperty(m, serialization)).WhereNotNull()) properties.AddProperty(property); return properties .OrderBy(p => p.Order ?? -1) .ThenBy(IsPropertyCollection) .ThenBy(GetPropertyTypeDepth) .ThenBy(p => p.PropertyName) .ToList(); }
/// <summary> /// Creates properties for the given <see cref="JsonObjectContract"/>. /// </summary> /// <param name="contract">The contract to create properties for.</param> /// <returns>Properties for the given <see cref="JsonObjectContract"/>.</returns> protected virtual IList<JsonProperty> CreateProperties(JsonObjectContract contract) { List<MemberInfo> members = GetSerializableMembers(contract.UnderlyingType); if (members == null) throw new JsonSerializationException("Null collection of seralizable members returned."); JsonPropertyCollection properties = new JsonPropertyCollection(contract); foreach (MemberInfo member in members) { JsonProperty property = CreateProperty(contract, member); if (property != null) properties.AddProperty(property); } return properties; }
protected override IList <JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { var serializableMembers = GetSerializableMembers(type).Cast <PropertyInfo>(); if (serializableMembers == null) { throw new JsonSerializationException("Null collection of seralizable members returned."); } var typeDefinition = _ServerConfiguration.GetScimTypeDefinition(type); var propertyCollection = new JsonPropertyCollection(type); foreach (var member in serializableMembers) { var property = CreateProperty(member, memberSerialization); if (property != null) { var state = _InstanceState; var propertyNameTable = state.NameTable; bool lockTaken = false; try { Monitor.Enter(propertyNameTable, ref lockTaken); property.PropertyName = state.NameTable.Add(property.PropertyName); IScimTypeAttributeDefinition attributeDefinition; if (typeDefinition != null && typeDefinition.AttributeDefinitions.TryGetValue(member, out attributeDefinition)) { // Internal json.net deserialization logic will hit the ShouldDeserialize delegate before checking property.Writable // Still, we'll set Writable to accurately reflect this property.Writable = attributeDefinition.Mutability != Mutability.ReadOnly; // deserializable? // setting property.Readable will shortcut the ShouldSerialize delegate // INTERNAL JSON.NET LOGIC // if (!property.Ignored && property.Readable && ShouldSerialize(writer, property, value) && IsSpecified(writer, property, value)) property.Readable = attributeDefinition.Mutability != Mutability.WriteOnly; // serializable? // Only attach a conditional deserialization delegate if the attribute is not ReadWrite. if (attributeDefinition.Mutability != Mutability.ReadWrite) { property.ShouldDeserialize = o => { if (attributeDefinition.Mutability == Mutability.ReadOnly) { return(false); } return(true); }; } // Only attach a conditional serialization delegate if the attribute is not Always returned. if (attributeDefinition.Returned != Returned.Always) { var existingShouldSerializeFunc = property.ShouldSerialize; property.ShouldSerialize = o => { if (attributeDefinition.Mutability == Mutability.WriteOnly || attributeDefinition.Returned == Returned.Never) { return(false); } var httpMethod = AmbientRequestService.HttpMethod; if (attributeDefinition.Returned == Returned.Default || (attributeDefinition.Returned == Returned.Request && (httpMethod == HttpMethod.Post || httpMethod == _Patch || httpMethod == HttpMethod.Put))) { var queryOptions = AmbientRequestService.QueryOptions; if (queryOptions.Attributes.Any() && !queryOptions.Attributes.Contains(property.PropertyName)) { return(false); } if (queryOptions.ExcludedAttributes.Any() && queryOptions.ExcludedAttributes.Contains(property.PropertyName)) { return(false); } } if (existingShouldSerializeFunc != null) { return(existingShouldSerializeFunc(o)); } return(true); }; } } } finally { if (lockTaken) { Monitor.Exit(propertyNameTable); } } propertyCollection.AddProperty(property); } } return(propertyCollection.OrderBy(p => p.Order ?? -1).ToList()); }
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { var serializableMembers = GetSerializableMembers(type).Cast<PropertyInfo>(); if (serializableMembers == null) throw new JsonSerializationException("Null collection of seralizable members returned."); var typeDefinition = _ServerConfiguration.GetScimTypeDefinition(type); var propertyCollection = new JsonPropertyCollection(type); foreach (var member in serializableMembers) { var property = CreateProperty(member, memberSerialization); if (property != null) { var state = _InstanceState; var propertyNameTable = state.NameTable; bool lockTaken = false; try { Monitor.Enter(propertyNameTable, ref lockTaken); property.PropertyName = state.NameTable.Add(property.PropertyName); IScimTypeAttributeDefinition attributeDefinition; if (typeDefinition != null && typeDefinition.AttributeDefinitions.TryGetValue(member, out attributeDefinition)) { // Internal json.net deserialization logic will hit the ShouldDeserialize delegate before checking property.Writable // Still, we'll set Writable to accurately reflect this property.Writable = attributeDefinition.Mutability != Mutability.ReadOnly; // deserializable? // setting property.Readable will shortcut the ShouldSerialize delegate // INTERNAL JSON.NET LOGIC // if (!property.Ignored && property.Readable && ShouldSerialize(writer, property, value) && IsSpecified(writer, property, value)) property.Readable = attributeDefinition.Mutability != Mutability.WriteOnly; // serializable? // Only attach a conditional deserialization delegate if the attribute is not ReadWrite. if (attributeDefinition.Mutability != Mutability.ReadWrite) { property.ShouldDeserialize = o => { if (attributeDefinition.Mutability == Mutability.ReadOnly) return false; return true; }; } // Only attach a conditional serialization delegate if the attribute is not Always returned. if (attributeDefinition.Returned != Returned.Always) { var existingShouldSerializeFunc = property.ShouldSerialize; property.ShouldSerialize = o => { if (attributeDefinition.Mutability == Mutability.WriteOnly || attributeDefinition.Returned == Returned.Never) return false; var httpMethod = AmbientRequestService.HttpMethod; if (attributeDefinition.Returned == Returned.Default || (attributeDefinition.Returned == Returned.Request && (httpMethod == HttpMethod.Post || httpMethod == _Patch || httpMethod == HttpMethod.Put))) { var queryOptions = AmbientRequestService.QueryOptions; if (queryOptions.Attributes.Any() && !queryOptions.Attributes.Contains(property.PropertyName)) return false; if (queryOptions.ExcludedAttributes.Any() && queryOptions.ExcludedAttributes.Contains(property.PropertyName)) return false; } if (existingShouldSerializeFunc != null) return existingShouldSerializeFunc(o); return true; }; } } } finally { if (lockTaken) Monitor.Exit(propertyNameTable); } propertyCollection.AddProperty(property); } } return propertyCollection.OrderBy(p => p.Order ?? -1).ToList(); }