コード例 #1
0
        private void ApplyMetadataToResource(IHalResource resource, ResourceContext resourceContext)
        {
            resourceContext.Resource = resource;
            resourceContext.MediaModule.ApplyResourceMeta(InternetMediaTypes.HalJson, resourceContext);

            // Add metadata to each embedded resource if present.
            if (resource.Embedded == null)
            {
                return;
            }

            foreach (IResource embeddedResource in resource.Embedded.Values)
            {
                // Check if the embedded resource is a collection of resources and if so
                // apply the metadata to each contained resource.
                if (embeddedResource is IEnumerable resourceColl)
                {
                    foreach (IHalResource childResource in resourceColl.OfType <IHalResource>())
                    {
                        ApplyMetadataToResource(childResource, resourceContext);
                    }

                    return;
                }

                // Add metadata to single embedded resource.
                if (embeddedResource is IHalResource halResource)
                {
                    ApplyMetadataToResource(halResource, resourceContext);
                }
            }
        }
コード例 #2
0
 /// <summary>
 /// Creates an instance of <see cref="HalEmbeddedResourceBuilder"/>.
 /// </summary>
 /// <param name="resource">The target resource.</param>
 public HalEmbeddedResourceBuilder(IHalResource resource) {
     if (resource == null) {
         throw new ArgumentNullException("resource");
     }
     _resource = resource;
     _linkCollection = new HalLinkCollection();
 }
コード例 #3
0
 /// <summary>
 /// Adds a link to the HAL resource.
 /// </summary>
 /// <param name="resource">The resource to which the link is added.</param>
 /// <param name="target">The resource that the link represents.</param>
 /// <param name="property">The property information of the target resource.</param>
 /// <param name="url">The URL helper used to create an HREF.</param>
 protected virtual void AddLink(IHalResource resource, IHalResource target, PropertyInfo property, UrlHelper url)
 {
     if (resource == null || url == null || target == null)
     {
         return;
     }
     try
     {
         var controller = GetControllerName(target);
         if (string.IsNullOrEmpty(controller))
         {
             Throw.NotSupported("Generating a HAL URI without a controller name is not supported.");
         }
         var    key  = GetKey(target, resource).ToString();
         string href = url.Link(this.RouteName, controller, key);
         AddLink(resource, href, object.ReferenceEquals(resource, target) ? "self" : property.Name);
     }
     catch (NotSupportedException ex)
     {
         if (ex.Message == "The resource type does not have a KeyAttribute defined.")
         {
             return;
         }
     }
 }
コード例 #4
0
        /// <summary>
        /// Recursively serializes the HAL resource to the output stream.
        /// </summary>
        /// <param name="writer">The <see cref="T:System.Xml.XmlWriter" /> to write to.</param>
        /// <param name="resource">The resource being written.</param>
        protected virtual void SerializeInnerResource(XmlWriter writer, IHalResource resource, string rel = "")
        {
            if (resource == null)
            {
                return;
            }

            // Open the node
            OpenResourceElement(writer, resource, rel);

            // Write the links collection into the output stream
            WriteLinks(writer, resource);

            // Write each non-HAL property (i.e. Resource State)
            WriteNonHalProperties(writer, resource);

            // Write each HAL property
            WriteHalProperties(writer, resource);

            if (typeof(IHalResourceCollection).IsAssignableFrom(resource.GetType()))
            {
                foreach (IHalResource innerResource in (IHalResourceCollection)resource)
                {
                    SerializeInnerResource(writer, innerResource);
                }
            }

            // Close out the node
            CloseResourceElement(writer);
        }
コード例 #5
0
        public static Uri GetLink(this IHalResource resource, string key, string tokenKey, object tokenValue)
        {
            if (resource == null)
            {
                throw new MissingLinkException(key, (Type)null);
            }

            return(resource.Links.GetLink(key, tokenKey, tokenValue));
        }
コード例 #6
0
 /// <summary>
 /// Opens the resource element node.
 /// </summary>
 /// <param name="writer">The <see cref="T:System.Xml.XmlWriter" /> to write to.</param>
 /// <param name="value">The value.</param>
 protected virtual void OpenResourceElement(XmlWriter writer, IHalResource value, string rel = "")
 {
     writer.WriteStartElement("resource");
     if (value != null)
     {
         writer.WriteAttributeString("rel", !string.IsNullOrEmpty(rel) ? rel : value.Rel);
         writer.WriteAttributeString("href", value.HRef);
     }
 }
コード例 #7
0
        public static Uri GetSelf(this IHalResource resource)
        {
            if (resource == null)
            {
                throw new MissingLinkException(HalResource.LinkKeySelf, (Type)null);
            }

            return(resource.Links.GetSelf());
        }
コード例 #8
0
        public static bool HasLink(this IHalResource resource, string key)
        {
            if (resource == null || string.IsNullOrWhiteSpace(key))
            {
                return(false);
            }

            return(resource.Links.HasLink(key));
        }
コード例 #9
0
        /// <summary>
        /// Embeds a resource within parent resource.
        /// </summary>
        /// <param name="embeddedResource">The resource to embed.</param>
        /// <param name="named">Optional name used to identity the embedded resource.</param>
        public void Embed(IHalResource embeddedResource, string named = null)
        {
            if (embeddedResource == null)
            {
                throw new ArgumentNullException(nameof(embeddedResource), "Resource to embedded not specified.");
            }

            EmbedResource(embeddedResource, named);
        }
コード例 #10
0
        public static Uri GetLink(this IHalResource resource, string key, IDictionary <string, object> tokens)
        {
            if (resource == null)
            {
                throw new MissingLinkException(key, (Type)null);
            }

            return(resource.Links.GetLink(key, tokens));
        }
コード例 #11
0
        public static Uri GetLink(this IHalResource resource, string key)
        {
            if (resource == null)
            {
                throw new MissingLinkException(key, (Type)null);
            }

            return(resource.Links.GetLink(key));
        }
コード例 #12
0
 /// <summary>
 /// Creates an instance of <see cref="HalEmbeddedResourceBuilder"/>.
 /// </summary>
 /// <param name="resource">The target resource.</param>
 public HalEmbeddedResourceBuilder(IHalResource resource)
 {
     if (resource == null)
     {
         throw new ArgumentNullException("resource");
     }
     _resource       = resource;
     _linkCollection = new HalLinkCollection();
 }
コード例 #13
0
        /// <summary>
        /// Adds a link to a resource that points to a collection.
        /// </summary>
        /// <param name="resource">The resource to which the link is added.</param>
        /// <param name="collection">The collection that the link targets.</param>
        /// <param name="parent">The parent resource containing the key attribute that links the <paramref name="resource" /> to the <paramref name="collection" />.</param>
        /// <param name="property">The property information of the target resource.</param>
        /// <param name="url">The URL helper used to create an HREF.</param>
        /// <remarks>
        /// There are scenarios that define what the relation is between the <paramref name="resource" /> and the <paramref name="collection" />:
        /// <list type="bullet">
        /// <item><strong>The resource and the collection reference the same object:</strong> the relation is <em>self</em></item>
        /// <item><strong>The resource and the collection refer to different objects:</strong> the relation is the property name of the collection</item>
        /// </list>
        /// </remarks>
        protected virtual void AddCollectionLink(IHalResource resource, IHalResourceCollection collection, IHalResource parent, PropertyInfo property, UrlHelper url)
        {
            if (resource == null || collection == null || parent == null || property == null || url == null)
            {
                return;
            }

            string key    = GetKey(resource, parent).ToString();
            string rel    = object.ReferenceEquals(resource, collection) ? "self" : property.Name;
            string filter = string.Empty;
            var    keys   = parent.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
                            .Where(x => x.GetCustomAttributes(typeof(KeyAttribute), true).Length > 0);
            PropertyInfo keyInfo = null;

            if (keys.Count() > 1) // multiple key properties
            {
                // sort them by [DataMember(Order)] and take the first one
                var keysWithDataMember = keys.Where(x => x.GetCustomAttributes(typeof(DataMemberAttribute), true).Length > 0);
                keyInfo = keysWithDataMember.OrderBy(x => ((DataMemberAttribute)x.GetCustomAttributes(typeof(DataMemberAttribute), true).First())
                                                     .Order).First();
            }
            else
            {
                keyInfo = keys.First();
            }

            var navigationKey = GetNavigationProperty(collection, parent);

            if (navigationKey == null)
            {
                return;
            }
            string controller = GetControllerName(collection);

            if (typeof(IEnumerable).IsAssignableFrom(navigationKey.PropertyType))
            {
                filter = string.Format("{0}/any({1}: {1}/{2} eq {3})", navigationKey.Name, parent.GetType().Name,
                                       keyInfo.Name, (keyInfo.PropertyType == typeof(string))
                    ? string.Format("'{0}'", key) : key);
            }
            else
            {
                filter = string.Format("{0}/{1} eq {2}", navigationKey.Name, keyInfo.Name,
                                       (keyInfo.PropertyType == typeof(string)) ? string.Format("'{0}'", key) : key);
            }
            string href = System.Web.HttpUtility.UrlDecode(url.Link(this.RouteName,
                                                                    new Dictionary <string, object>
            {
                { "controller", controller },
                { "$filter", filter },
                { "mainargument", null }
            }));

            AddLink(resource, href, rel);
        }
コード例 #14
0
 /// <summary>
 /// Adds the specified resource to the collection.
 /// </summary>
 /// <param name="resource">The HAL resource.</param>
 /// <exception cref="T:System.NotSupportedException">
 /// The 'Add' method requires a type derived from Geocrest.Model.Resource.
 /// </exception>
 public void Add(IHalResource resource)
 {
     if (resource.GetType().IsSubclassOf(typeof(Resource)))
     {
         this.resources.Add((T)resource);
     }
     else
     {
         throw new NotSupportedException("The 'Add' method requires a type derived from Geocrest.Model.Resource.");
     }
 }
コード例 #15
0
 public Task <IHalDeleteResult> Delete(IHalResource resource, IHalPersisterStrategy strategy = null)
 {
     strategy = strategy ?? GetDefaultPersisterStrategy(resource);
     if (strategy == null)
     {
         throw new HalPersisterException("No persister found for resource: " + resource);
     }
     return(Task <IHalDeleteResult>
            .Factory
            .StartNew(() => strategy.Delete(resource)));
 }
コード例 #16
0
 /// <summary>
 /// Write the HAL links collection into the output stream
 /// </summary>
 /// <param name="writer">The <see cref="T:System.Xml.XmlWriter" /> to write to.</param>
 /// <param name="value">The value.</param>
 protected virtual void WriteLinks(XmlWriter writer, IHalResource value)
 {
     Throw.IfArgumentNull(writer, "writer");
     if (value != null && value.Links != null)
     {
         foreach (var link in value.Links.Where(x => !(x is SelfLink)))
         {
             writer.WriteStartElement("link");
             writer.WriteAttributeString("rel", link.Rel);
             writer.WriteAttributeString("href", link.HRef);
             writer.WriteEndElement();
         }
     }
 }
コード例 #17
0
        public IHalDeleteResult Delete(IHalResource resource)
        {
            var link = resource.Links.FirstOrDefault(l => l.Rel == "self");

            if (link == null)
            {
                throw new HalPersisterException("No link found for deleting: " + resource);
            }
            var result = HttpClient.DeleteAsync(link.Href).Result;

            return(new HalDeleteResult {
                Success = result.IsSuccessStatusCode
            });
        }
コード例 #18
0
        /// <summary>
        /// Writes each property of the type <see cref="T:Geocrest.Model.IHalResource"/> or
        /// <see cref="T:Geocrest.Model.IHalResourceCollection"/> into the output stream
        /// </summary>
        /// <param name="writer">The <see cref="T:System.Xml.XmlWriter" /> to write to.</param>
        /// <param name="value">The value.</param>
        protected virtual void WriteHalProperties(XmlWriter writer, IHalResource value)
        {
            Throw.IfArgumentNull(writer, "writer");
            Throw.IfArgumentNull(value, "value");

            // add all HalResources to a dictionary for embedding.
            var properties = value.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
                             .Where(x => typeof(IHalResource).IsAssignableFrom(x.PropertyType) && x.GetIndexParameters()
                                    .Length == 0);

            foreach (var property in properties)
            {
                var item = property.GetValue(value, null);
                SerializeInnerResource(writer, (IHalResource)item, GetDataMemberName(property));
            }
        }
コード例 #19
0
        /// <summary>
        /// Gets the name of the controller first by configuration then by convention.
        /// </summary>
        /// <param name="resource">The resource.</param>
        /// <returns></returns>
        private static string GetControllerName(IHalResource resource)
        {
            var type = resource.GetType();

            if (typeof(IHalResourceCollection).IsAssignableFrom(type))
            {
                type = type.GetGenericArguments()[0];
            }
            string controllerName;

            if (!configMappings.TryGetValue(type, out controllerName))
            {
                var p = PluralizationService.CreateService(new System.Globalization.CultureInfo("en-US"));
                controllerName = p.Pluralize(type.Name).ToLower();
            }
            return(controllerName);
        }
コード例 #20
0
        /// <summary>
        /// Write the HAL links collection into the reserved <i>_links</i> JSON property
        /// http://tools.ietf.org/html/draft-kelly-json-hal-06#section-4.1.1
        /// </summary>
        /// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter" /> to write to.</param>
        /// <param name="value">The value.</param>
        /// <param name="serializer">The calling serializer.</param>
        protected virtual void WriteLinks(JsonWriter writer, IHalResource value, JsonSerializer serializer)
        {
            Throw.IfArgumentNull(writer, "writer");
            Throw.IfArgumentNull(serializer, "serializer");

            var linksConverter = serializer.Converters.FirstOrDefault(x => x.CanConvert(typeof(IList <Link>)));

            if (linksConverter != null)
            {
                writer.WritePropertyName("_links");
                writer.WriteStartArray();
                if (value != null)
                {
                    linksConverter.WriteJson(writer, value.Links, serializer);
                }
                writer.WriteEndArray();
            }
        }
コード例 #21
0
        /// <summary>
        /// Enriches the entity with HAL links by recursively enriching any property
        /// that inherits from <see cref="T:Geocrest.Model.IHalResource"/>
        /// </summary>
        /// <param name="resource">The resource.</param>
        /// <param name="url">The URL.</param>
        protected virtual void EnrichEntity(IHalResource resource, UrlHelper url)
        {
            if (resource == null)
            {
                return;
            }
            var properties = resource.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
                             .Where(x => typeof(IHalResource).IsAssignableFrom(x.PropertyType));

            // add a self link to the resource
            AddLink(resource, resource, null, url);

            foreach (PropertyInfo property in properties)
            {
                var propValue = property.GetValue(resource, null);
                var propType  = property.PropertyType;
                if (propValue == null)
                {
                    continue;
                }
                if (typeof(IHalResourceCollection).IsAssignableFrom(propType))
                {
                    var child = (IHalResourceCollection)propValue;

                    // add a self link to the collection (will use oData to create the link)
                    AddCollectionLink(child, child, resource, property, url);
                    // add link to parent
                    AddCollectionLink(resource, child, resource, property, url);

                    foreach (IHalResource item in (IHalResourceCollection)propValue)
                    {
                        // continue recursive enriching
                        EnrichEntity(item, url);
                    }
                }
                else
                {
                    // add a link to the parent resource to the child resource
                    AddLink(resource, (IHalResource)propValue, property, url);
                    // continue recursive enriching
                    EnrichEntity((IHalResource)propValue, url);
                }
            }
        }
コード例 #22
0
        /// <summary>
        /// Adds a link to the HAL resource.
        /// </summary>
        /// <param name="resource">The resource to which the link is added.</param>
        /// <param name="href">The HREF to the target resource.</param>
        /// <param name="rel">The relation of the target resource.</param>
        protected virtual void AddLink(IHalResource resource, string href, string rel)
        {
            if (resource == null)
            {
                return;
            }
            if (string.IsNullOrEmpty(href))
            {
                Throw.NotSupported("Links must have a valid HREF.");
            }
            if (string.IsNullOrEmpty(rel))
            {
                Throw.NotSupported("Links must have a relation defined.");
            }

            resource.AddLink(rel.ToLower() == "self" ?
                             new SelfLink(href) :
                             new Link(rel, href));
        }
コード例 #23
0
        private static PropertyInfo GetNavigationProperty(IHalResource primary, IHalResource foreign)
        {
            Type type = null;

            if (typeof(IHalResourceCollection).IsAssignableFrom(primary.GetType()))
            {
                type = primary.GetType().GetGenericArguments()[0];
            }
            else
            {
                type = primary.GetType();
            }
            var property = type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                           .SingleOrDefault(x => (typeof(IHalResourceCollection).IsAssignableFrom(x.PropertyType) &&
                                                  x.PropertyType.GetGenericArguments()[0] == foreign.GetType()) ||
                                            x.PropertyType == foreign.GetType());

            return(property);
        }
コード例 #24
0
        /// <summary>
        /// Returns the value of the property decorated with a
        /// <see cref="T:System.ComponentModel.DataAnnotations.KeyAttribute" />.
        /// </summary>
        /// <param name="resource">A HAL resource containing a key attribute.</param>
        /// <param name="parent">The parent resource if <paramref name="resource"/> is a HAL collection.</param>
        /// <returns>
        /// Returns an object containing the value of the key.
        /// </returns>
        private static object GetKey(IHalResource resource, IHalResource parent)
        {
            Type         type      = null;
            PropertyInfo keyProp   = null;
            IHalResource keyHolder = null;

            if (typeof(IHalResourceCollection).IsAssignableFrom(resource.GetType())) // if collection then get key from parent
            {
                type      = parent.GetType();
                keyHolder = parent;
            }
            else // get key from resource itself
            {
                type      = resource.GetType();
                keyHolder = resource;
            }
            var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            var keys       = properties.Where(x => x.GetCustomAttributes(typeof(KeyAttribute), true).Length > 0);

            if (keys.Count() > 1) // multiple key properties
            {
                // sort them by [DataMember(Order)] and take the first one
                var keysWithDataMember = keys.Where(x => x.GetCustomAttributes(typeof(DataMemberAttribute), true).Length > 0);
                keyProp = keysWithDataMember.OrderBy(x => ((DataMemberAttribute)x.GetCustomAttributes(typeof(DataMemberAttribute), true).First())
                                                     .Order).FirstOrDefault();
            }
            else
            {
                keyProp = keys.FirstOrDefault();
            }

            if (keyProp == null)
            {
                Throw.NotSupported("The resource type does not have a KeyAttribute defined.");
            }
            var key = keyProp.GetGetMethod().Invoke(keyHolder, null);

            if (key == null)
            {
                Throw.NotSupported(string.Format("Unable to retrieve the key for resource type '{0}'.", type.FullName));
            }
            return(key);
        }
コード例 #25
0
        /// <summary>
        /// Called during serialization to write an object of the specified type to the specified writeStream.
        /// </summary>
        /// <param name="type">The type of object to write.</param>
        /// <param name="value">The object to write.</param>
        /// <param name="writeStream">The <see cref="T:System.IO.Stream" /> to which to write.</param>
        /// <param name="content">The <see cref="T:System.Net.Http.HttpContent" /> for the content being written.</param>
        /// <param name="transportContext">The <see cref="T:System.Net.TransportContext" />.</param>
        /// <returns>
        /// A <see cref="T:System.Threading.Tasks.Task" /> that will write the value to the stream.
        /// </returns>
        public override System.Threading.Tasks.Task WriteToStreamAsync(System.Type type, object value, System.IO.Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext)
        {
            return(Task.Factory.StartNew(() =>
            {
                var settings = new XmlWriterSettings();
                settings.Indent = false;
                settings.OmitXmlDeclaration = false;

                var writer = XmlWriter.Create(writeStream, settings);

                IHalResource resource = null;

                SerializeInnerResource(writer, (IHalResource)value);

                writer.Flush();
                writer.Close();
                return resource;
            }));
        }
コード例 #26
0
        /// <summary>
        /// Writes the properties that are not HAL properties (i.e. are not of the type
        /// <see cref="T:Geocrest.Model.IHalResource"/> or
        /// <see cref="T:Geocrest.Model.IHalResourceCollection"/>)
        /// to the output stream. This is the resource state.
        /// </summary>
        /// <param name="writer">The <see cref="T:System.Xml.XmlWriter" /> to write to.</param>
        /// <param name="value">The value.</param>
        protected virtual void WriteNonHalProperties(XmlWriter writer, IHalResource value)
        {
            Throw.IfArgumentNull(writer, "writer");
            Throw.IfArgumentNull(value, "value");

            // exclude HalResource types and IList<Link> type
            var properties = value.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
                             .Where(x => !typeof(IHalResource).IsAssignableFrom(x.PropertyType) && !typeof(IList <Link>)
                                    .IsAssignableFrom(x.PropertyType));

            // serialize each property and it's value
            foreach (var property in properties)
            {
                var propertyValue = property.GetValue(value, null);

                // class members must opt in to be included in the ouput serialization by having a
                // [DataMember] on the property
                var dataMember = property.GetCustomAttributes(typeof(DataMemberAttribute), false).Length == 0 ? false : true;

                // classes can exclude serialization of properties that contain default
                // values by adding [DataMember(EmitDefaultValue = false)]
                var emitDefault = property.GetCustomAttributes(typeof(DataMemberAttribute), false).Length == 0 ?
                                  true : // <-default behavior
                                  ((DataMemberAttribute)property.GetCustomAttributes(typeof(DataMemberAttribute), false)
                                   .Single()).EmitDefaultValue;

                // classes can also exclude serialization of properties regardless of value
                // by adding [IgnoreDataMember] to the property
                var ignore = property.GetCustomAttributes(typeof(IgnoreDataMemberAttribute), false).Length == 0 ? false : true;

                // and serialize
                if (dataMember && !ignore && (emitDefault == true || !IsDefault(propertyValue)))
                {
                    var dataContract = (DataContractAttribute)property.PropertyType.GetCustomAttributes(typeof(DataContractAttribute),
                                                                                                        false).SingleOrDefault();
                    var ns         = dataContract != null ? dataContract.Namespace : string.Empty;
                    var serializer = new DataContractSerializer(property.PropertyType, GetDataMemberName(property), ns);
                    serializer.WriteObject(writer, propertyValue);
                }
            }
        }
コード例 #27
0
        /// <summary>
        /// Writes each property of the type <see cref="T:Geocrest.Model.IHalResource"/> or
        /// <see cref="T:Geocrest.Model.IHalResourceCollection"/> into the reserved
        /// <i>_embedded</i> JSON property
        /// http://tools.ietf.org/html/draft-kelly-json-hal-06#section-4.1.2
        /// </summary>
        /// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter" /> to write to.</param>
        /// <param name="value">The value.</param>
        /// <param name="serializer">The calling serializer.</param>
        protected virtual void WriteHalProperties(JsonWriter writer, IHalResource value, JsonSerializer serializer)
        {
            Throw.IfArgumentNull(writer, "writer");
            Throw.IfArgumentNull(value, "value");
            Throw.IfArgumentNull(serializer, "serializer");
            writer.WritePropertyName("_embedded");
            writer.WriteStartObject();

            // add all HalResources to a dictionary for embedding.
            var properties = value.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
                             .Where(x => typeof(IHalResource).IsAssignableFrom(x.PropertyType));

            foreach (var property in properties)
            {
                writer.WritePropertyName(GetDataMemberName(property));
                var item = property.GetValue(value, null);
                serializer.Serialize(writer, item);
            }

            writer.WriteEndObject();
        }
コード例 #28
0
        /// <summary>
        /// Writes the properties that are not HAL properties (i.e. are not of the type
        /// <see cref="T:Geocrest.Model.IHalResource"/> or
        /// <see cref="T:Geocrest.Model.IHalResourceCollection"/>)
        /// to the output JSON. This is the resource state.
        /// </summary>
        /// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter" /> to write to.</param>
        /// <param name="value">The value.</param>
        /// <param name="serializer">The calling serializer.</param>
        protected virtual void WriteNonHalProperties(JsonWriter writer, IHalResource value, JsonSerializer serializer)
        {
            Throw.IfArgumentNull(writer, "writer");
            Throw.IfArgumentNull(value, "value");
            Throw.IfArgumentNull(serializer, "serializer");

            // exclude HalResource types and IList<Link> type
            var properties = value.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
                             .Where(x => !typeof(IHalResource).IsAssignableFrom(x.PropertyType) && !typeof(IList <Link>)
                                    .IsAssignableFrom(x.PropertyType));

            // serialize each property and it's value
            foreach (var property in properties)
            {
                var propertyValue = property.GetValue(value, null);

                // class members must opt in to be included in the ouput serialization by having a
                // [DataMember] on the property
                var dataMember = property.GetCustomAttributes(typeof(DataMemberAttribute), false).Length == 0 ? false : true;

                // classes can exclude serialization of properties that contain null/default
                // values by adding [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
                var emitDefault = property.GetCustomAttributes(typeof(JsonPropertyAttribute), false).Length == 0 ?
                                  NullValueHandling.Include : // <-default behavior
                                  ((JsonPropertyAttribute)property.GetCustomAttributes(typeof(JsonPropertyAttribute), false)
                                   .Single()).NullValueHandling;

                // classes can also exclude serialization of properties regardless of value
                // by adding [JsonIgnore] to the property
                var ignore = property.GetCustomAttributes(typeof(JsonIgnoreAttribute), false).Length == 0 ? false : true;

                // and serialize
                if (dataMember && !ignore && emitDefault == NullValueHandling.Include)
                {
                    writer.WritePropertyName(GetDataMemberName(property));
                    serializer.Serialize(writer, propertyValue);
                }
            }
        }
コード例 #29
0
        /// <summary>
        /// Recursively serializes the HAL resource to the output JSON.
        /// </summary>
        /// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter" /> to write to.</param>
        /// <param name="resource">The resource being written.</param>
        /// <param name="serializer">The calling serializer.</param>
        protected virtual void SerializeInnerResource(JsonWriter writer, IHalResource resource, JsonSerializer serializer)
        {
            if (resource == null)
            {
                return;
            }

            // Open the object
            writer.WriteStartObject();

            // Write the links collection into the reserved _links JSON property
            WriteLinks(writer, resource, serializer);

            // Write each non-HAL property (i.e. Resource State)
            WriteNonHalProperties(writer, resource, serializer);

            // Write each HAL property into the reserved _embedded JSON property
            // http://tools.ietf.org/html/draft-kelly-json-hal-06#section-4.1.2
            WriteHalProperties(writer, resource, serializer);

            // End the object
            writer.WriteEndObject();
        }
コード例 #30
0
ファイル: HalDocument.cs プロジェクト: erixn/Hal9000.Json.Net
 /// <summary>
 /// Creates an instance of <see cref="HalDocument"/>.
 /// </summary>
 /// <param name="resource">The hypermedia aware resource.</param>
 /// <param name="linkCollection">A collection of hypermedia links.</param>
 /// <param name="embeddedResourceCollection">A collection of embedded resources.</param>
 internal HalDocument(IHalResource resource, HalLinkCollection linkCollection,
                      HalEmbeddedResourceCollection embeddedResourceCollection)
     : this(resource, linkCollection) {
     _embeddedResourceCollection = embeddedResourceCollection;
 }
コード例 #31
0
ファイル: HalDocument.cs プロジェクト: erixn/Hal9000.Json.Net
 /// <summary>
 /// Creates an instance of <see cref="HalDocument"/>.
 /// </summary>
 /// <param name="resource">The hypermedia aware resource.</param>
 /// <param name="linkCollection">A collection of hypermedia links.</param>
 internal HalDocument(IHalResource resource, HalLinkCollection linkCollection) {
     _resource = resource;
     _linkCollection = linkCollection;
 }
コード例 #32
0
 /// <summary>
 /// Creates an instance of <see cref="HalDocument"/>.
 /// </summary>
 /// <param name="resource">The hypermedia aware resource.</param>
 /// <param name="linkCollection">A collection of hypermedia links.</param>
 internal HalDocument(IHalResource resource, HalLinkCollection linkCollection)
 {
     _resource       = resource;
     _linkCollection = linkCollection;
 }
コード例 #33
0
 /// <summary>
 /// Creates an instance of <see cref="HalDocument"/>.
 /// </summary>
 /// <param name="resource">The hypermedia aware resource.</param>
 /// <param name="linkCollection">A collection of hypermedia links.</param>
 /// <param name="embeddedResourceCollection">A collection of embedded resources.</param>
 internal HalDocument(IHalResource resource, HalLinkCollection linkCollection,
                      HalEmbeddedResourceCollection embeddedResourceCollection)
     : this(resource, linkCollection)
 {
     _embeddedResourceCollection = embeddedResourceCollection;
 }