Skip to content

Support for properties renamed with [DataMember] in OData models #511

Closed
@brainboost

Description

@brainboost
  1. Put the [DataContract] and [DataMember] attributes on the OData model
    [DataContract]
    public class Contact
    {
        [DataMember]
        public int ContactId { get; set; }
        [DataMember(Name = "first_name")]
        public string FirstName { get; set; }
        [DataMember]
        public string LastName { get; set; }
        [DataMember]
        public string Email { get; set; }
        [DataMember]
        public string Phone { get; set; }
        [DataMember]
        public List<Address> Addresses { get; set; }
    }
  1. Prepare the unit test expecting the property renamed in the contract
    public class DefaultModelTypeBuilderTest
    {
     ...
        [Fact]
        public void substituted_type_should_have_renamed_with_attribute_properties_from_original_type()
        {
            // arrange
            var modelBuilder = new ODataConventionModelBuilder();
            modelBuilder.EntitySet<Contact>( "Contacts" );

            var context = NewContext( modelBuilder.GetEdmModel() );
            var originalType = typeof( Contact );

            // act
            var substitutedType = originalType.SubstituteIfNecessary( context );

            // assert
            substitutedType.Should().HaveProperty<string>(nameof( Contact.FirstName ) );
        }
  1. Get the failed this test and some others, as the property FirstName is disappeared from the type as well as from the Swagger generated model documentation.

In order to fix this behavior I made changes in DefaultModelTypeBuilder, particularly in lines 106-115, method GenerateTypeIfNeeded.

 if ( !structuralProperties.TryGetValue( property.Name, out var structuralProperty ) )
 {
     var name = GetNameFromAttribute( property );
     if ( string.IsNullOrEmpty( name ) || !structuralProperties.TryGetValue( name, out structuralProperty ) )
     {
         clrTypeMatchesEdmType = false;
         continue;
     }
 }

...
        static string GetNameFromAttribute( MemberInfo property )
        {
            return property.GetCustomAttribute<System.Runtime.Serialization.DataMemberAttribute>()?.Name;
        }

I'd be happy to provide PR with the working solution as I did my changes in the forked repo. Should I?

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions