Skip to content

JsonRequestBodySerializer with Required Properties check #68

@netclectic

Description

@netclectic

I made a custom serializer that will check for required properties when serializing from an object that uses the Required property of the JsonProperty attribute. I doubt if its something that you would want to include by default but I thought I'd throw it out there in case anybody else was looking some to do the same.

I guess it would add a bit of extra overhead to serializing, but it seems to work ok with no noticable impact on performance with the limited testing I've done so far.

public class JsonRequestBodyWithRequiredPropertiesSerializer : RequestBodySerializer
    {
        /// <summary>
        /// Gets or sets the serializer settings to pass to JsonConvert.SerializeObject
        /// </summary>
        public JsonSerializerSettings JsonSerializerSettings { get; set; }

        /// <inheritdoc/>
        public override HttpContent SerializeBody<T>(T body, RequestBodySerializerInfo info)
        {
            if (EqualityComparer<T>.Default.Equals(body, default(T)))
                return null;

            var jsonSerializerSettings = JsonSerializerSettings ?? new JsonSerializerSettings() { ContractResolver = new DefaultContractResolver() };
            var contract = (JsonObjectContract)jsonSerializerSettings.ContractResolver.ResolveContract(typeof(T));
            foreach (JsonProperty property in contract.Properties)
            {
                Required? propertyRequired = property.Required;
                Required resolvedRequired = property.Ignored ? Required.Default : propertyRequired ?? contract.ItemRequired ?? Required.Default;
                if (resolvedRequired == Required.Always && null == property.ValueProvider.GetValue(body))
                {
                    throw new JsonSerializationException($"Required property '{property.UnderlyingName}' is null.");
                }
            }

            var content = new StringContent(JsonConvert.SerializeObject(body, JsonSerializerSettings));
            content.Headers.ContentType.MediaType = "application/json";
            return content;
        }
    }

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions