private Type FindExtensionType(Type resourceType, string extensionSchemaIdentifier) { Type extensionType = null; if (resourceType != null) { extensionType = _ServerConfiguration.GetResourceExtensionType(resourceType, extensionSchemaIdentifier); while (extensionType == null && resourceType != typeof(Resource)) { if (resourceType != null) { resourceType = resourceType.BaseType; extensionType = _ServerConfiguration.GetResourceExtensionType(resourceType, extensionSchemaIdentifier); } } } return(extensionType); }
/// <summary> /// Reads the JSON representation of the object. /// </summary> /// <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader" /> to read from.</param> /// <param name="objectType">Type of the object.</param> /// <param name="existingValue">The existing value of object being read.</param> /// <param name="serializer">The calling serializer.</param> /// <returns>The object value.</returns> /// <exception cref="System.Exception"> /// In order for Owin.Scim to support resource extensions, the serialization /// process is uniquely designed. Therefore, your Resource type objects must /// contain at mimimum, a default empty constructor (which may be private). /// </exception> public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { object instance = null; var jsonReader = reader; var contract = serializer.ContractResolver.ResolveContract(objectType); if (contract.DefaultCreator == null) { // Let's try to dynamically determine the type to instantiate based upon the schemas collection // of the resource. This adds support for polymorphism if objectType == typeof(Resource), which is abstract. var jObject = JObject.Load(reader); var schemasKey = jObject.FindKeyCaseInsensitive(ScimConstants.Schemas.Key); if (schemasKey != null) { var schemasValue = jObject[schemasKey]; if (schemasValue != null) { var schemaIdentifiers = ((JArray)schemasValue).ToObject <ISet <string> >(); foreach (var schemaBindingRule in _ServerConfiguration.SchemaBindingRules) { if (schemaBindingRule.Predicate(schemaIdentifiers, objectType)) { instance = schemaBindingRule.Target.CreateInstance(); jsonReader = jObject.CreateReader(); // create a new reader from the token break; } } } } } else { instance = contract.DefaultCreator(); } if (instance == null) { throw new ScimException( HttpStatusCode.InternalServerError, @"In order for Owin.Scim to support resource extensions, the serialization process is uniquely designed. Therefore, your Resource type objects must contain at mimimum, a default empty constructor (which may be private).".RemoveMultipleSpaces()); } try { serializer.Populate(jsonReader, instance); } catch (FormatException e) { throw new ScimException( HttpStatusCode.InternalServerError, string.Format( "Owin.Scim was unable to deserialize the json. Exception detail: {0}{1}", Environment.NewLine, e.Message)); } var resource = instance as Resource; if (resource != null && resource.ExtensionSerialization != null) { foreach (var kvp in resource.ExtensionSerialization) { var extensionType = _ServerConfiguration.GetResourceExtensionType(objectType, kvp.Key); if (extensionType == null) { continue; // This is either a readOnly attribute or an unknown/unsupported extension } // extension value may be null if (kvp.Value.HasValues) { resource.AddExtension((ResourceExtension)kvp.Value.ToObject(extensionType)); } else { resource.AddNullExtension(extensionType, kvp.Key); } } } return(resource); }