RehanSaeed / Schema.NET

Schema.org objects turned into strongly typed C# POCO classes for use in .NET. All classes can be serialized into JSON/JSON-LD and XML, typically used to represent structured data in the head section of html page.
MIT License
640 stars 80 forks source link

The JSON property name for 'Schema.NET.IHospital.OpeningHours' collides with another property. #603

Open fewless2019 opened 1 year ago

fewless2019 commented 1 year ago

Describe the bug

Can not serialize a schema.net.Physician while using schema.net.MedicalWebPage

Properties with the same name.

hospital ->CivicStructureAndEmergencyServiceAndMedicalOrganization ->

[JsonPropertyName("openingHours")]
[JsonPropertyOrder(307)]
[JsonConverter(typeof(ValuesJsonConverter))]
public override OneOrMany<string> OpeningHours { get; set; }

Physician-> MedicalBusinessAndMedicalOrganization -> LocalBusinessAndOrganization ->

[JsonPropertyName("openingHours")]
[JsonPropertyOrder(238)]
[JsonConverter(typeof(ValuesJsonConverter))]
public OneOrMany<string> OpeningHours { get; set; }

Steps to reproduce

//Site Default
MedicalAudience medicalAudience = new MedicalAudience()
{
    RequiredMinAge = 0,
    RequiredMaxAge = 21,
    SuggestedMinAge = 0,
    SuggestedMaxAge = 21,
    SuggestedGender = "All genders"
};

MedicalWebPage website = new MedicalWebPage()
{
    MedicalAudience = medicalAudience
};

Physician physician = new Physician()
{
    Name = doctorProfilePage.DisplayName,
    Description = doctorProfilePage.CurrentPage.SeoSettings.Description,
};

if (Uri.IsWellFormedUriString(doctorProfilePage.Image, UriKind.Absolute))
{
    Uri outUri;

    if (Uri.TryCreate(doctorProfilePage.Image, UriKind.RelativeOrAbsolute, out outUri))
    {
        ImageObject image = new ImageObject()
        {
            ThumbnailUrl = outUri,
            Url = outUri
        };

        physician.Image = image;
        physician.Photo = image;
        website.Image = image;
    }
}

physician.Address = doctorProfilePage.GetSchemaAddress();
physician.Telephone = doctorProfilePage.GetSchemaPhone();
physician.Identifier = doctorProfilePage.ProfileId.ToString();
physician.Id = baseUri;

//website.MainEntity = mainHospital;
website.About = physician;

return website.ToHtmlEscapedString()  //Fails here. on ToHtmlEscapedString

Stack trace

System.InvalidOperationException: The JSON property name for 'Schema.NET.IHospital.OpeningHours' collides with another property.
at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_SerializerPropertyNameConflict(Type type, String propertyName) 
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.AddProperty(JsonPropertyInfo jsonPropertyInfo, PropertyHierarchyResolutionState& state) 
at System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver.AddMembersDeclaredBySuperType(JsonTypeInfo typeInfo, Type currentType, Boolean shouldCheckMembersForRequiredMemberAttribute, PropertyHierarchyResolutionState& state) 
at System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver.PopulateProperties(JsonTypeInfo typeInfo) 
at System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver.CreateTypeInfoCore(Type type, JsonConverter converter, JsonSerializerOptions options) 
at System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver.GetTypeInfo(Type type, JsonSerializerOptions options) 
at System.Text.Json.JsonSerializerOptions.GetTypeInfoNoCaching(Type type) 
at System.Text.Json.JsonSerializerOptions.CachingContext.CreateCacheEntry(Type type, CachingContext context) 
--- End of stack trace from previous location --- 
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.Configure() 
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.g__ConfigureSynchronized|161_0() 
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo.Configure() 
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.ConfigureProperties() 
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.Configure() 
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.g__ConfigureSynchronized|161_0() 
at System.Text.Json.JsonSerializer.Serialize(Utf8JsonWriter writer, Object value, Type inputType, JsonSerializerOptions options) 
at Schema.NET.ValuesJsonConverter.WriteObject(Utf8JsonWriter writer, Object value, JsonSerializerOptions options) in /_/Source/Common/ValuesJsonConverter.cs:line 184
at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state) 
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer) 
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state) 
at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state) 
at System.Text.Json.Serialization.JsonConverter`1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state) 
at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.Serialize(Utf8JsonWriter writer, T& rootValue, Object rootValueBoxed, Boolean isInvokedByPolymorphicConverter) 
at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.SerializeAsObject(Utf8JsonWriter writer, Object rootValue, Boolean isInvokedByPolymorphicConverter) 
at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.Serialize(Utf8JsonWriter writer, T& rootValue, Object rootValueBoxed, Boolean isInvokedByPolymorphicConverter) 
at System.Text.Json.JsonSerializer.WriteString[TValue](TValue& value, JsonTypeInfo`1 jsonTypeInfo) 
at Schema.NET.Thing.ToString() in /_/Source/Common/Thing.Partial.cs:line 23 
at SeattleChildrens.Features.SchemaExtensions.GenerateSchema(IHtmlHelper helper, IWebPage viewModel) in C:\repos\SeattleChildrens.orgCore\SeattleChildrens.Features\Infrastructure\Extensions\SchemaExtensions.cs:line 593

Properties with the same Name hospital ->CivicStructureAndEmergencyServiceAndMedicalOrganization ->

[JsonPropertyName("openingHours")]
[JsonPropertyOrder(307)]
[JsonConverter(typeof(ValuesJsonConverter))]
public override OneOrMany<string> OpeningHours { get; set; }

Physician-> MedicalBusinessAndMedicalOrganization -> LocalBusinessAndOrganization ->

[JsonPropertyName("openingHours")]
[JsonPropertyOrder(238)]
[JsonConverter(typeof(ValuesJsonConverter))]
public OneOrMany<string> OpeningHours { get; set; }

Expected behaviour

Unique names and ability to serialize.

Schema objects

schema.net.Physician schema.net.MedicalWebPage

Turnerj commented 1 year ago

Hi @fewless2019 - I can't recreate the problem you've describe by using the steps you've mentioned. Can you tell me the version of .NET you're using, whether you're pulling in your own version of System.Text.Json (and what version that is), and also have a look over the steps to reproduce that you've provided.

Based on the exception message, I don't think the problem is to do with the Physician inheritance but the Hospital inheritance. Specifically CivicStructureAndEmergencyServiceAndMedicalOrganization has OpeningHours and so does LocalBusinessAndOrganizationAndPlace. And even then, the exception refers to the interface IHospital, not the implementation.

The strange part though is these combined types have several properties that are overridden, not just OpeningHours and I don't see anything special about OpeningHours in terms of how it is defined in Schema.NET nor any reference in your steps to reproduce.

fewless2019 commented 1 year ago

we are using .net 6

attattachedatched is the Json that produces the error. I am a bit lost.

We use Schema.NET.MedicalWebPage then we fill out the info for the Schema.NET.Physician nothing to do with the hospital. is even included when we go to serialize this.

how ever when i used Schema.NET.Person instead of Schema.NET.Physician it works fine.

Thanks,

David Fewless Senior Web Developer, Diagram

[A close-up of a clock Description automatically generated with medium confidence] e: @.**@.> p: 630-491-2622 w: www.wearediagram.comhttp://www.wearediagram.com/ he/him [cid:c0afc9ac-d344-4d09-bfe9-33d4e05546a9] https://twitter.com/wearediagram [cid:54944cde-315f-4968-a540-0571ae6566b1] https://www.linkedin.com/company/19151275/admin/ [cid:22682a1f-e095-42d0-991e-71db8b4a0d15] https://www.instagram.com/heydiagram


From: James Turner @.> Sent: Thursday, June 8, 2023 9:23 AM To: RehanSaeed/Schema.NET @.> Cc: David Fewless @.>; Mention @.> Subject: Re: [RehanSaeed/Schema.NET] The JSON property name for 'Schema.NET.IHospital.OpeningHours' collides with another property. (Issue #603)

Hi @fewless2019https://github.com/fewless2019 - I can't recreate the problem you've describe by using the steps you've mentioned. Can you tell me the version of .NET you're using, whether you're pulling in your own version of System.Text.Json (and what version that is), and also have a look over the steps to reproduce that you've provided.

Based on the exception message, I don't think the problem is to do with the Physician inheritance but the Hospital inheritance. Specifically CivicStructureAndEmergencyServiceAndMedicalOrganization has OpeningHours and so does LocalBusinessAndOrganizationAndPlace. And even then, the exception refers to the interface IHospital, not the implementation.

The strange part though is these combined types have several properties that are overridden, not just OpeningHours and I don't see anything special about OpeningHours in terms of how it is defined in Schema.NET nor any reference in your steps to reproduce.

— Reply to this email directly, view it on GitHubhttps://github.com/RehanSaeed/Schema.NET/issues/603#issuecomment-1582575081, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AWNF4UCUY64AQXNVILFGCCLXKHG33ANCNFSM6AAAAAAY4VGQEU. You are receiving this because you were mentioned.Message ID: @.***>

fewless2019 commented 1 year ago

We are using .Net6

Attached is the Json.

I fixed this by creating my own physician class and removing the hospital affiliation variable.

/////

///// A hospital with which the physician or office is affiliated. ///// //[JsonPropertyName("hospitalAffiliation")] //[JsonPropertyOrder(407)] //[JsonConverter(typeof(ValuesJsonConverter))] //public OneOrMany HospitalAffiliation { get; set; }

Thanks,

David Fewless Senior Web Developer, Diagram

[A close-up of a clock Description automatically generated with medium confidence] e: @.**@.> p: 630-491-2622 w: www.wearediagram.comhttp://www.wearediagram.com/ he/him @. https://twitter.com/wearediagram @. https://www.linkedin.com/company/19151275/admin/ @.*** https://www.instagram.com/heydiagram

From: James Turner @.> Sent: Thursday, June 8, 2023 9:23 AM To: RehanSaeed/Schema.NET @.> Cc: David Fewless @.>; Mention @.> Subject: Re: [RehanSaeed/Schema.NET] The JSON property name for 'Schema.NET.IHospital.OpeningHours' collides with another property. (Issue #603)

Hi @fewless2019https://github.com/fewless2019 - I can't recreate the problem you've describe by using the steps you've mentioned. Can you tell me the version of .NET you're using, whether you're pulling in your own version of System.Text.Json (and what version that is), and also have a look over the steps to reproduce that you've provided.

Based on the exception message, I don't think the problem is to do with the Physician inheritance but the Hospital inheritance. Specifically CivicStructureAndEmergencyServiceAndMedicalOrganization has OpeningHours and so does LocalBusinessAndOrganizationAndPlace. And even then, the exception refers to the interface IHospital, not the implementation.

The strange part though is these combined types have several properties that are overridden, not just OpeningHours and I don't see anything special about OpeningHours in terms of how it is defined in Schema.NET nor any reference in your steps to reproduce.

— Reply to this email directly, view it on GitHubhttps://github.com/RehanSaeed/Schema.NET/issues/603#issuecomment-1582575081, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AWNF4UCUY64AQXNVILFGCCLXKHG33ANCNFSM6AAAAAAY4VGQEU. You are receiving this because you were mentioned.Message ID: @.**@.>>

kirk-marple commented 2 weeks ago

Just ran across this issue, since I saw a similar issue serializing 'MedicalStudy'.

I'm getting this error: The JSON property name for 'Schema.NET.IDrug.Funding' collides with another property.

This is using .NET 8.0 version of System.Text.Json.

kirk-marple commented 1 week ago

Looks like my serialization issue was due to 'Drug' being a subclass of both Product and Substance, and the 'Funding' property is defined in both places.

Not sure how Schema.NET is supposed to handle these kinds of situations?

I had to create a private version of the library, and remove 'Product' from the JSON-LD file to get it working.

cc: @Turnerj @RehanSaeed