Open htzhang2 opened 4 years ago
It is working for me on 3.1. Maybe include a sample of how you are configuring the odata pipeline and the EdmModel
.
//public void ConfigureServices(IServiceCollection services) {
services.AddOData();
services.AddMvcCore(options =>
{
foreach (var outputFormatter in options.OutputFormatters.OfType
foreach (var inputFormatter in options.InputFormatters.OfType<InputFormatter>().Where(x => x.SupportedMediaTypes.Count == 0))
{
inputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/prs.odatatestxx-odata"));
}
})
// public void Configure(...) {
app.UseMvc(routeBuilder =>
{
routeBuilder.EnableDependencyInjection();
routeBuilder.Expand().Select().Filter().Count().OrderBy();
});
Try to create a EDMModel but don't know how to set routeName and routePrefix ?
routeBuilder.MapODataServiceRoute("api", "api", GetEdmModel());
private static IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<EntityClaimsModel>("EntityClaims");
return builder.GetEdmModel();
}
// This code crashed my application
My controller:
[Route("api/claims/admin/ns/{nameSpace}/entities/{entityId}")] public class EntityClaimsController : ControllerBase {
[HttpGet("odata/users")]
[EnableQuery]
public async Task<IActionResult> GetEntityUserClaimInfo(string nameSpace, string entityId, ODataQueryOptions opts)
Log shows EntityClaimsModel has no key defined:
EventName: StatelessReplicaNewHealthReport Category: Health EventInstanceId { 92afcf39-5a54-41e2-b702-5b8abde7b568} PartitionId {c3502651-1f23-4277-94a3-7736f0138e29} ReplicaId 132431326198692503 SourceId=System.RA Property=ReplicaOpenStatus HealthState=Warning TTL=922337203685477 SequenceNumber=132431326394614196 Description='Replica had multiple failures during open on _Node_0. API call: IStatelessServiceInstance.Open(); Error = System.InvalidOperationException (-2146233079) The entity set 'EntityClaims' is based on type 'VWAC.Claims.ClaimsService.Domain.Model.EntityClaimsModel' that has no keys defined. at Microsoft.AspNet.OData.Builder.ODataModelBuilder.ValidateModel(IEdmModel model) at Microsoft.AspNet.OData.Builder.ODataConventionModelBuilder.ValidateModel(IEdmModel model) at Microsoft.AspNet.OData.Builder.ODataConventionModelBuilder.GetEdmModel()
But EntityClaimsModel does have key defined:
public class EntityClaimsModel : BaseModel { private readonly string entityId;
/// <summary>Gets the entity identifier.</summary>
/// <value>The entity identifier.</value>
[Required]
[Key]
public string EntityId => entityId;
...
Hey @htzhang2
It seems you using ODataQueryOptions in a Non-OData AspNetCore application. In the first example, you can try removing the [FromQuery]
and see if it works.
In order to fully use OData, you can use ODataRoute
instead of Route
, ODataController
instead of ControllerBase
.
hi @KenitoInc , removing the [FromQuery] works but not really an option as it breaks the external contract (serialized json rather than separated input parameters ). what might be a good way to work around this odd problem?
I have a ASPNet Core 3.1 project, controller GET method is trying to use ODataQueryOptions as parameter:
using Microsoft.AspNet.OData.Query;
[HttpGet("api/products")] public async Task<ODataPaginationResult> GetProducts(
[fromQuery] ODataQueryOptions opts)
{
// code to get products
}
// However, on Swagger this opts parameter shows as body object. // On Postman, it show 415 (unsupported media type) if uri is http://localhost:[port]/api/products?$top=1
// Similar code works for ASPNet 4.7.2 project on Postman
Seems OData structure is different between ASPNet and Core. Please suggest a work-around on ASPNMet Core 3.1