-
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
Implement a concept of "Required" properties #29861
Comments
.... if So: public class Person
{
public string Name { get; set; }
public int Age { get; set; }
} would fail the deserialize, but: public class Person
{
public string? Name { get; set; }
public int Age { get; set; }
} ... would let it succeed. |
If we implement |
Having another look at https://github.com/dotnet/corefx/issues/37485, it looks like there's already another issue that is effectively asking for the same thing. Perhaps we should just close this and use the other issue to track work here? |
I believe we should have the support for This issue talks more directly to the issue at hand, so I would prefer keeping this one as a feature request. cc @steveharter |
From @pranavkm (https://github.com/dotnet/corefx/issues/37485#issuecomment-501482970):
|
Required was discussed but didn't meet the bar for 3.0 in lieu of other features. A workaround is to create a custom converter (pending feature) and override the Read method. |
Fair enough. I think we're ok with that for this release. We can keep this issue around to track the feature work for the Future. |
Virtually all my model's properties have Newtonsoft Json's |
I agree such behaviour would be very desirable to ensure compiler checks with nullable reference types are not undermined at runtime by incorrect JSON (defeating the purpose of "nullable enable"). However this is perhaps best handled via the separate issue #1256. A Required attribute would at least allow a reasonable manual workaround for this in the meantime though. NB: I have sadly decided to roll back my conversion to System.Text.Json since as now using nullable reference types I don't want to go back to adding lots of null run-time checks. |
I see that this issue has been considered a nice to have, but I would like to point out that the workaround of creating a custom converter isn't an extensible one, as you would either need to create a custom converter for every class with required properties, or create a generic one that allows you to pass the names of all the required fields to the converter, while also handling the specifics of actually converting the values. |
What about the progress of this issue? It would be glad to have the JsonRequired attribute used in Newtonsoft.Json implemented in System.Text.Json |
Also interested in a progress update on this issue. The workaround described here is not viable when you are working with many different classes. |
@MythicManiac how do you get around the fact that you have non nullable type ( |
The same way as how you can declare non-nullable types that are filled in the constructor, meaning it's fine to declare such properties as long as they are populated appropriately during the creation of the object. That is another good point however, the compiler as it is right now does not seem to issue an error if you attempt to initialize an object without all of it's non-nullable fields set to non-null values during initialization. How related that is to this issue I'm unsure, but it does surprise me how lax the compiler is with nullability checks like this. |
I don't follow. If you have object initialization path that ensures that after creation of the instance these properties are not null then that is not a responsibility of static analysis to guess that a property that is said to be non null can be null. Just like setting a value of non nullable property to null just generates a warning on that part where it is setting the value. That won't affect the rest of the analysis because you are breaking the assumption at one point.
It does though?
yields warning:
|
FWIW see also the C# proposal for required properties: dotnet/csharplang#3630. If the metadata is available for these properties, it could be leveraged by STJ during deserialization. |
@Hoffs I'm confident I have a project with the issue I presented, but I don't have it available here right now and given it's going a bit off topic, let's just leave it as IMO it'd be better to explicitly disallow non-nullable fields for the serializer, or alternatively make it respect and enforce the constraints they imply. |
This feature is being moved out of .NET 7 into the Future milestone. We will continue to follow the C# proposal for required properties as a possible integration. |
I've internally added support for |
namespace System.Text.Json.Serialization
{
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property,
AllowMultiple=false)]
public sealed class JsonRequiredAttribute : JsonAttribute
{
public JsonRequiredAttribute();
}
}
namespace System.Text.Json.Serialization.Metadata
{
public abstract partial class JsonPropertyInfo
{
public bool IsRequired { get; set; }
}
} |
AB#1130869
API proposal:
Current situation
There's no way to indicate that if an object doesn't have a particular property that serialization should fail.
For example:
Trying to deserialize the above json as a
Person
will succeed, even though it's been indicated that the name attribute is required, and is missing.Describe the solution you'd like
System.Text.Json should respect either
System.ComponentModel.DataAnnotations.RequiredAttribute
or a new attribute (likely extendingSystem.Text.Json.JsonAttribute
) and error when an attempt is made to serialize an object which doesn't have that property.Describe alternatives you've considered
Using
System.ComponentModel.DataAnnotations.RequiredAttribute
might be troublesome because it could indicate Requirement in a different context. The alternative is that users implement their own "Required" functionality (and likely get it wrong or incomplete).CC @pranavkm who I talked about this with.
The text was updated successfully, but these errors were encountered: