I'm developing a .NET Core 2.2 web app, using ABP and OData, and I've followed this guide. After setting everything up, I can query http://localhost:21021/odata
and get the following result:
{"result":{"entitySets":[{"url":"Empresas","name":"Empresas","title":null,"typeAnnotation":null},{"url":"Users","name":"Users","title":null,"typeAnnotation":null}],"singletons":[],"functionImports":[],"typeAnnotation":null},"targetUrl":null,"success":true,"error":null,"unAuthorizedRequest":false,"__abp":true}
But anything I try with my entities, like hitting http://localhost:21021/odata/Empresas
, just results in a 404.
What could be the problem?
Startup.cs
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// MVC
services.AddMvc(
options => options.Filters.Add(new CorsAuthorizationFilterFactory(_defaultCorsPolicyName))
);
services.AddOData();
// Workaround: https://github.com/OData/WebApi/issues/1177
services.AddMvcCore(options =>
{
foreach (var outputFormatter in options.OutputFormatters.OfType<ODataOutputFormatter>().Where(_ => _.SupportedMediaTypes.Count == 0))
{
outputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/prs.odatatestxx-odata"));
}
foreach (var inputFormatter in options.InputFormatters.OfType<ODataInputFormatter>().Where(_ => _.SupportedMediaTypes.Count == 0))
{
inputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/prs.odatatestxx-odata"));
}
});
IdentityRegistrar.Register(services);
AuthConfigurer.Configure(services, _appConfiguration);
// ... SignalR, CORS, Swagger, etc ...
return services.AddAbp<EcfWebHostModule>(
// Configure Log4Net logging
options => options.IocManager.IocContainer.AddFacility<LoggingFacility>(
f => f.UseAbpLog4Net().WithConfig("log4net.config")
)
);
public void Configure(IApplicationBuilder app)
{
app.UseAbp(options => { options.UseAbpRequestLocalization = false; }); // Initializes ABP framework.
// ... UseCors, UseStaticFiles, UseAuthentication, UseAbpRequestLocalization, UseSignalR ...
app.UseOData(builder =>
{
builder.EntitySet<EmpresaEntity>("Empresas").EntityType.Expand().Filter().OrderBy().Page();
builder.EntitySet<User>("Users").EntityType.Expand().Filter().OrderBy().Page();
});
app.UseUnitOfWork(options =>
{
options.Filter = httpContext =>
{
return httpContext.Request.Path.Value.StartsWith("/odata");
};
});
// ... Swagger ...
app.UseMvc(routes =>
{
routes.MapODataServiceRoute(app);
routes.MapRoute(
name: "defaultWithArea",
template: "{area}/{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
EmpresaController.cs
public class EmpresaController : AbpODataEntityController<EmpresaEntity>, ITransientDependency
{
public EmpresaController(IRepository<EmpresaEntity> repository)
: base(repository)
{
}
}
EmpresaEntity.cs
public sealed class EmpresaEntity : FullAuditedEntity
{
public string Cnpj { get; set; }
public string Nome { get; set; }
}
Finally solved it.
Just had to change the name of the controller to match the string passed as parameter in the startup class. It wasn't clear from the documentation that was how it worked.
builder.EntitySet<EmpresaEntity>("Empresas").EntityType.Expand().Filter().OrderBy().Page();
and
EmpresasController