Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configuration Binding a dictionary with a key that has empty value skips the key as well #66229

Closed
vidhyapg opened this issue Mar 5, 2022 · 6 comments
Labels
area-Extensions-Configuration breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. bug
Milestone

Comments

@vidhyapg
Copy link

vidhyapg commented Mar 5, 2022

I am using Configuration Binding to read a config file. Empty dictionary value leads to not generating an entry for key as well.

Here is where I bind the configuration to a type defined in my project DistributedQueueConfig

                        var opts = new DistributedQueueConfig();
                        var config = hostContext.Configuration.GetSection("queueConfig");
                        // bind manually
                        config.Bind(opts);

Attached the json file used.

This is examining opts after Bind.

opts.Namespaces[0].Queues.Count
2
opts.Namespaces[1].Queues.Count
1
opts.Namespaces[1].Queues
Count = 1
    [0]: {[q3, {CognitiveServices.Batch.Common.DistributedQueueConfiguration.Models.QueueProperties}]}

q4 which has empty value does have an entry in the dictionary which is not expected. When I used JsonSerializer.Deserialize(), I can see q4 in the object. It is valid for a queue to not have any queueproperties fields set, but still should show up in the list of queues. I tried both BinderOptions which has no effect. This seems to be a bug.

    /// <summary>
    /// Top level of the config json
    /// </summary>
    public class DistributedQueueConfig
    {
        /// <summary>
        /// Contains list of namespaces.
        /// </summary>
        [JsonPropertyName("namespaces")]
        public IList<QueueNamespaces> Namespaces { get; set; }
    }

    public class QueueNamespaces
    {
        /// <summary>
        /// Namespace value
        /// </summary>
        [JsonPropertyName("namespace")]
        public string Namespace { get; set; }

        /// <summary>
        /// Map of queue name and its properties.
        /// </summary>
        [JsonPropertyName("queues")]
        public Dictionary<string, QueueProperties> Queues { get; set; } = new ();
    }

    public class QueueProperties
    {
        /// <summary>
        /// The date when the queue is marked to be dequeueOnly.
        /// Used to determine if queue is AvailableForEnqueueing.
        /// </summary>
        [JsonPropertyName("creationDate")]
        public DateTimeOffset? CreationDate { get; set; }

        /// <summary>
        /// The date when the queue is marked to be dequeueOnly.
        /// Used to determine if queue is AvailableForEnqueueing.
        /// </summary>
        [JsonPropertyName("dequeueOnlyMarkedDate")]
        public DateTimeOffset? DequeueOnlyMarkedDate { get; set; } = default(DateTimeOffset);
    }

queue_config.json

{
	"queueConfig": {
		"namespaces": [
			{
				"namespace": "devnortheurope",
				"queues": {
					"q1": {
						"dequeueOnlyMarkedDate": "2022-01-20T12:49:03.395150-08:00"
					},
					"q2": {
						"dequeueOnlyMarkedDate": "2022-01-20T12:49:03.395150-08:00"
					}
				}
			},
			{
				"namespace": "devnortheurope2",
				"queues": {
					"q3": {
						"dequeueOnlyMarkedDate": "2022-01-20T12:49:03.395150-08:00"
					},
					"q4": {
					}
				}
			}
		]
	}
}
@pranavkm pranavkm transferred this issue from dotnet/aspnetcore Mar 5, 2022
@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label Mar 5, 2022
@ghost
Copy link

ghost commented Mar 5, 2022

Tagging subscribers to this area: @dotnet/area-extensions-configuration
See info in area-owners.md if you want to be subscribed.

Issue Details

I am using Configuration Binding to read a config file. Empty dictionary value leads to not generating an entry for key as well.

Here is where I bind the configuration to a type defined in my project DistributedQueueConfig

                    var opts = new DistributedQueueConfig();
                    var config = hostContext.Configuration.GetSection("queueConfig");
                    // bind manually
                    config.Bind(opts);

Attached the json file used.

This is examining opts after Bind.

opts.Namespaces[0].Queues.Count
2
opts.Namespaces[1].Queues.Count
1
opts.Namespaces[1].Queues
Count = 1
[0]: {[q3, {CognitiveServices.Batch.Common.DistributedQueueConfiguration.Models.QueueProperties}]}

q4 which has empty value does have an entry in the dictionary which is not expected. When I used JsonSerializer.Deserialize(), I can see q4 in the object. It is valid for a queue to not have any queueproperties fields set, but still should show up in the list of queues. I tried both BinderOptions which has no effect. This seems to be a bug.

/// <summary>
/// Top level of the config json
/// </summary>
public class DistributedQueueConfig
{
    /// <summary>
    /// Contains list of namespaces.
    /// </summary>
    [JsonPropertyName("namespaces")]
    public IList<QueueNamespaces> Namespaces { get; set; }
}

public class QueueNamespaces
{
    /// <summary>
    /// Namespace value
    /// </summary>
    [JsonPropertyName("namespace")]
    public string Namespace { get; set; }

    /// <summary>
    /// Map of queue name and its properties.
    /// </summary>
    [JsonPropertyName("queues")]
    public Dictionary<string, QueueProperties> Queues { get; set; } = new ();
}

public class QueueProperties
{
    /// <summary>
    /// The date when the queue is marked to be dequeueOnly.
    /// Used to determine if queue is AvailableForEnqueueing.
    /// </summary>
    [JsonPropertyName("creationDate")]
    public DateTimeOffset? CreationDate { get; set; }

    /// <summary>
    /// The date when the queue is marked to be dequeueOnly.
    /// Used to determine if queue is AvailableForEnqueueing.
    /// </summary>
    [JsonPropertyName("dequeueOnlyMarkedDate")]
    public DateTimeOffset? DequeueOnlyMarkedDate { get; set; } = default(DateTimeOffset);
}

queue_config.json
{
"queueConfig": {
"namespaces": [
{
"namespace": "devnortheurope",
"queues": {
"q1": {
"dequeueOnlyMarkedDate": "2022-01-20T12:49:03.395150-08:00"
},
"q2": {
"dequeueOnlyMarkedDate": "2022-01-20T12:49:03.395150-08:00"
}
}
},
{
"namespace": "devnortheurope2",
"queues": {
"q3": {
"dequeueOnlyMarkedDate": "2022-01-20T12:49:03.395150-08:00"
},
"q4": {
}
}
}
]
}
}

Author: vidhyapg
Assignees: -
Labels:

untriaged, area-Extensions-Configuration

Milestone: -

@maryamariyan maryamariyan removed the untriaged New issue has not been triaged by the area owner label Mar 15, 2022
@maryamariyan maryamariyan added this to the Future milestone Mar 15, 2022
@ghost
Copy link

ghost commented May 18, 2023

Tagging subscribers to this area: @dotnet/area-extensions-configuration
See info in area-owners.md if you want to be subscribed.

Issue Details

I am using Configuration Binding to read a config file. Empty dictionary value leads to not generating an entry for key as well.

Here is where I bind the configuration to a type defined in my project DistributedQueueConfig

                        var opts = new DistributedQueueConfig();
                        var config = hostContext.Configuration.GetSection("queueConfig");
                        // bind manually
                        config.Bind(opts);

Attached the json file used.

This is examining opts after Bind.

opts.Namespaces[0].Queues.Count
2
opts.Namespaces[1].Queues.Count
1
opts.Namespaces[1].Queues
Count = 1
    [0]: {[q3, {CognitiveServices.Batch.Common.DistributedQueueConfiguration.Models.QueueProperties}]}

q4 which has empty value does have an entry in the dictionary which is not expected. When I used JsonSerializer.Deserialize(), I can see q4 in the object. It is valid for a queue to not have any queueproperties fields set, but still should show up in the list of queues. I tried both BinderOptions which has no effect. This seems to be a bug.

    /// <summary>
    /// Top level of the config json
    /// </summary>
    public class DistributedQueueConfig
    {
        /// <summary>
        /// Contains list of namespaces.
        /// </summary>
        [JsonPropertyName("namespaces")]
        public IList<QueueNamespaces> Namespaces { get; set; }
    }

    public class QueueNamespaces
    {
        /// <summary>
        /// Namespace value
        /// </summary>
        [JsonPropertyName("namespace")]
        public string Namespace { get; set; }

        /// <summary>
        /// Map of queue name and its properties.
        /// </summary>
        [JsonPropertyName("queues")]
        public Dictionary<string, QueueProperties> Queues { get; set; } = new ();
    }

    public class QueueProperties
    {
        /// <summary>
        /// The date when the queue is marked to be dequeueOnly.
        /// Used to determine if queue is AvailableForEnqueueing.
        /// </summary>
        [JsonPropertyName("creationDate")]
        public DateTimeOffset? CreationDate { get; set; }

        /// <summary>
        /// The date when the queue is marked to be dequeueOnly.
        /// Used to determine if queue is AvailableForEnqueueing.
        /// </summary>
        [JsonPropertyName("dequeueOnlyMarkedDate")]
        public DateTimeOffset? DequeueOnlyMarkedDate { get; set; } = default(DateTimeOffset);
    }

queue_config.json

{
	"queueConfig": {
		"namespaces": [
			{
				"namespace": "devnortheurope",
				"queues": {
					"q1": {
						"dequeueOnlyMarkedDate": "2022-01-20T12:49:03.395150-08:00"
					},
					"q2": {
						"dequeueOnlyMarkedDate": "2022-01-20T12:49:03.395150-08:00"
					}
				}
			},
			{
				"namespace": "devnortheurope2",
				"queues": {
					"q3": {
						"dequeueOnlyMarkedDate": "2022-01-20T12:49:03.395150-08:00"
					},
					"q4": {
					}
				}
			}
		]
	}
}
Author: vidhyapg
Assignees: -
Labels:

bug, area-Extensions-Configuration

Milestone: Future

@tarekgh
Copy link
Member

tarekgh commented May 20, 2023

Should be fixed by #86485

@tarekgh tarekgh closed this as completed May 20, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Jun 19, 2023
@tarekgh tarekgh added the breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. label Jul 27, 2023
@ghost ghost added the needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet label Jul 27, 2023
@tarekgh
Copy link
Member

tarekgh commented Jul 27, 2023

Filed the breaking change doc dotnet/docs#36431

@tarekgh tarekgh removed the needs-breaking-change-doc-created Breaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet label Jul 27, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Extensions-Configuration breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. bug
Projects
None yet
Development

No branches or pull requests

4 participants