ZEXSM / OData.QueryBuilder

OData.QueryBuilder - library for creating complex OData queries (OData version 4.01) based on data models with linq syntax.
MIT License
71 stars 31 forks source link

Provide support for JsonPropertyName attribute #99

Open jackdunncode opened 2 years ago

jackdunncode commented 2 years ago
public class BcBookingHeader
{
    [JsonPropertyName("id")]
    public string? Id { get; set; }

    [JsonPropertyName("bookinglines")]
    public List<BcBookingLine>? BookingLines { get; set; }
}
var odataQueryBuilder = new ODataQueryBuilder(_settings.BaseUrl);
var uri = odataQueryBuilder
    .For<BcBookingHeader>("bookings")
    .ByList()
    .Expand(header => header.BookingLines)
    .ToUri();

Output: ../bookings?$expand=BookingLines

Desired output: ../bookings?$expand=bookinglines


Please add support for respecting and applying name specified in JsonPropertyName attribute. Possibly as configuration as setting?

jackdunncode commented 2 years ago

Helper method for getting attribute value:

public class JsonAttributeHelper
{
    public static string GetJsonPropertyName<T>(Expression<Func<T, object>> expr)
        where T : class
    {
        Expression body = expr.Body is UnaryExpression unary ? unary.Operand : expr.Body;

        if (body is MemberExpression memberEx)
        {
            return memberEx.Member.GetCustomAttribute<JsonPropertyNameAttribute>()?.Name;
        }

        throw new ArgumentException("Invalid member access");
    }
}
ZEXSM commented 2 years ago

JsonPropertyNameAttribute - I would like to avoid this dependency in this library. I can suggest adding a mechanism to intercept the entry of the property name. This will get the JsonPropertyNameAttribute and write down the desired property name

casually-creative commented 2 years ago

JsonPropertyNameAttribute - I would like to avoid this dependency in this library. I can suggest adding a mechanism to intercept the entry of the property name. This will get the JsonPropertyNameAttribute and write down the desired property name

Could I suggest a similar approach to how Entity Framework does it with it's Fluent API Configuration? Example:

public class SomeEntityConfiguration : IEntityTypeConfiguration<SomeEntity>
{
    public void Configure(EntityTypeBuilder<SomeEntity> entity)     
    {
        entity
            .Property(e => e.Id)
            .HasColumnName("entity_id");
    }
}

and then in the DbContext:

modelBuilder.ApplyConfigurationsFromAssembly(typeof(SomeEntityConfiguration).Assembly);

This keeps the entity classes clean of configuration logic.

Also I believe this is a much desired feature, at least for me. The odata endpoint that you're implementing might be casing the entities and properties differently then how you might want to case them in your code. I see this as an urgent feature :)

PS: the ability to do the same for the entity name itself would be a bonus. This way we can avoid odataQueryBuilder.For<SomeEntity>("some_entity").

prochnowc commented 1 year ago

FYI: There is a json independent attribute DataMemberAttribute which is also recognized by Newtonsoft.Json