-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Binding to non-null IEnumerable doesn't work #36390
Comments
I ran into this issue today and came to the same conclusion as @brockallen |
We could treat a non-null but empty collection as something that we add to. This way an empty collection would be treated the same as a null collection. |
Can you handle the non-null and non empty collection case too? e.g. IEnumerable _data = new[] { "c" }; The Config data can have default value if it does not exist in the JSON and can be overwritten if it exists in the JSON. I find this problem when I try to bind the IdentityServer4 Client For version 1.5.2, the allowedGrantTypes is IEnumerable and has default value (it is changed to ICollection in latest dev version). I try to put the client settings in the JSON file but the AllowedGrantTypes can't be overwritten because it is IEnumerable with default value. It works find if the IEnumberable is null or if it is ICollection
|
@ajcvickers - any updates on when this is going to be fixed? Thank you! |
@lbogdanov It's currently in the backlog, which means it's not going to be fixed in an upcoming release. Beyond that, it will depend on prioritization against other work. |
The correct behaviour is to overwrite. Not append. |
For .NET 5.0: https://github.com/dotnet/runtime/blob/master/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs#L327 @lbogdanov basically this is never going to be fixed because the team doesn't care enough to do it. Instead of fixing bugs they would rather just keep piling on new features, because bugs are boring and don't get blog posts written about them. |
Basically, why don't we check if the instance runtime type is some collectionInterface = FindOpenGenericInterface(typeof(ICollection<>), instance.GetType());
if (collectionInterface != null)
{
BindCollection(instance, collectionInterface, config, options);
} I've checked this on both empty and not empty initialized |
It seems reasonable to treat an empty enumerable in the same way as null. I'm less inclined to examine the runtime type unless we have some precedent for that. Additionally, it doesn't fix the cases where folks backed the property with Enumerable.Empty or an Array. cc @eerhardt @maryamariyan |
Related: #46988 (which could also solve this problem) |
I'd like to look at this if it's still 'up-for-grabs'? |
Not a problem. I've pinged you in discord, also feel free to post your questions here if you rather keep them in the open. |
Binding should work for an IEnumerable property instantiated with a collection type. In the case of IEnumerable, rather than just checking the type of the property, we also now check the instance type to see if it's `ICollection` based in order to populate it. Fix dotnet#36390
@maryamariyan I'm going through 1st party asks. From what I can see, this is still open, we're still interested in doing this, but it can't fit this release any more? |
For triage, will discuss with @halter73 on next steps for this. |
I have the same problem, and use this workaround to avoid analyzer complaint: public class Config
{
public IEnumerable<string> Data { get; set; } = null!;
} But I agree to solve this. No one would understand to make it work without complain from analyzer. |
@maryamariyan - do you know if there's been any more thought on this one? |
Here's a summary of where we're at with this issue: When we set this issue up for grabs the first time, the desired fix was not clearly defined. As part of closing the original PR we uncovered that there is a subtle difference between configuration binding and System.Text.Json deserialization. Because with configuration we have to append data from multiple sources but deserialization has a single source of truth and that is why we don't think of configuration binding as a deserializer. (In a way for the configuration case we are mapping what is already been de-serialized to a POCO.) This comment covers where we left off from the original PR: #52514 (comment) We decided since then that the proper fix here for this issue would be very similar to runtime/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs Lines 449 to 482 in 0ee10e9
@SteveDunn we could set it up for grabs if you're open to making the above fix. Thanks again for staying engaged on this. /cc @halter73 @davidfowl |
Hi @maryamariyan . Yes very happy to have another crack at this one. Will be great to get it done! |
closed via @66131 |
AB#1277574
When using the binding feature in the config system, for IEnumerable collections that have a default, non-null value, the collection is never assigned into the target model. For example:
For this json:
and this application code:
The output is:
I'd expect it to print "2".
I'd argue the issue is in
BindInstance
and explicit handling forIEnumerable
should be made (much like the check forIsArray
https://github.com/aspnet/Configuration/blob/dev/src/Microsoft.Extensions.Configuration.Binder/ConfigurationBinder.cs#L281).The text was updated successfully, but these errors were encountered: