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);
        }
Exemple #2
0
        /// <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);
        }