Model aliasing doesn't work when not using DataContract and DataMember attributes
Open
@xuzhg is already working on this.
Since Aug 17, 2021.
followup
investigated
- Dominant language
- C#
- Stars
- 505
- Forks
- 186
- PR merge metrics
- No merged PRs in 30d
Description
I was trying to add OData query options support with model aliasing to an ASP.NET Core API project without using OData routing.
Assemblies affected
- Microsoft.AspNetCore.OData 8.0.1
- Microsoft.OData.ModelBuilder 1.0.6
Reproduce steps
-
Registering the OData services
// Api/Startup.cs public void ConfigureServices(IServiceCollection services) { services.AddControllers().AddOData(options => { options .AddRouteComponents(GetEdmModel()) .Filter() .OrderBy() .SetMaxTop(100) .EnableNoDollarQueryOptions = true; }); -
Building the EDM model
// Api/Startup.cs private static IEdmModel GetEdmModel() { var builder = new ODataConventionModelBuilder(); var account = builder.EntityType<Core.Models.Account>(); account.Property(e => e.Code).Name = "code"; account.Property(e => e.Name).Name = "name"; return builder.GetEdmModel(); } // Core/Models/Account.cs namespace Core.Models { public class Account { public string Code { get; set; } public string Name { get; set; } } } -
Creating the controller
// Api/Controllers/AccountsController public class AccountsController : ControllerBase { [HttpGet] public async Task<IEnumerable<Api.Models.Account>> Get( ODataQueryOptions<Core.Models.Account> options, CancellationToken cancellationToken = default) { var coreModels = await Service.ListAsync(options, cancellationToken); return Mapper.Map<IEnumerable<Api.Models.Account>>(); } } -
Execute a GET request (simplified and formatted for clarity)
GET /accounts ?filter=code eq 'F4' &orderby=name
Expected result
A list of accounts.
Actual result
Microsoft.OData.ODataException: Could not find a property named 'name' on type 'Core.Models.Account'.
Additional detail
When I switched to using the DataContext and DataMember attributes, everything worked as expected. However, this is not an option as it causes the Core layer to depend on the API layer.
// Api/Startup.cs
private static IEdmModel GetEdmModel()
{
var builder = new ODataConventionModelBuilder();
builder.EntityType<Core.Models.Account>();
return builder.GetEdmModel();
}
// Core/Models/Account.cs
namespace Core.Models
{
[DataContract]
public class Account
{
[DataMember(Name = "code")]
public string Code { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
}
}
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.