用于 net core 3.1 Web Api 问题的自定义 OData 格式化程序
Custom OData Formatter for netcore 3.1 WebApi Issues
所以我正在构建一个必须通过 OData 使用的服务,我很难弄清楚如何向它添加自定义格式化程序。我需要我的 OData 序列化程序在序列化数据时忽略空值。我创建了这两个来实现这一点:
public class SmartODataSerializerProvider : DefaultODataSerializerProvider
{
private readonly SmartODataEntityTypeSerializer _entityTypeSerializer;
public SmartODataSerializerProvider(IServiceProvider rootContainer)
: base(rootContainer)
{
_entityTypeSerializer = new SmartODataEntityTypeSerializer(this);
}
public override ODataEdmTypeSerializer GetEdmTypeSerializer(Microsoft.OData.Edm.IEdmTypeReference edmType)
{
// Support for Entity types AND Complex types
if (edmType.Definition.TypeKind == EdmTypeKind.Entity || edmType.Definition.TypeKind == EdmTypeKind.Complex)
return _entityTypeSerializer;
else
return base.GetEdmTypeSerializer(edmType);
}
}
和
public class SmartODataEntityTypeSerializer : ODataResourceSerializer
{
public SmartODataEntityTypeSerializer(ODataSerializerProvider provider)
: base(provider) { }
/// <summary>
/// Only return properties that are not null
/// </summary>
/// <param name="structuralProperty">The EDM structural property being written.</param>
/// <param name="resourceContext">The context for the entity instance being written.</param>
/// <returns>The property be written by the serilizer, a null response will effectively skip this property.</returns>
public override Microsoft.OData.ODataProperty CreateStructuralProperty(Microsoft.OData.Edm.IEdmStructuralProperty structuralProperty, ResourceContext resourceContext)
{
var property = base.CreateStructuralProperty(structuralProperty, resourceContext);
return property.Value != null ? property : null;
}
}
这些是在另一个堆栈溢出问题上提供的。但是,当我尝试使用此序列化程序时出现问题。我已经有一个正在工作的 odata 端点(它只是用 null 序列化所有内容)并且当我将以下配置应用于它时,我不断在没有它的情况下工作的同一个 EP 上得到“404 Not Found”。
app.UseEndpoints(endpoints =>
{
endpoints.MapODataRoute("odata", "odata", a =>
{
a.AddService(Microsoft.OData.ServiceLifetime.Singleton, typeof(IEdmModel), sp => GetEdmModel(app.ApplicationServices));
a.AddService(Microsoft.OData.ServiceLifetime.Singleton, typeof(ODataSerializerProvider), sp => new SmartODataSerializerProvider(sp));
});
endpoints.EnableDependencyInjection();
//endpoints.MapODataRoute("odata", "odata", GetEdmModel(app.ApplicationServices));
endpoints.MapControllers();
});
这是端点设置。我注释掉了使它工作但没有自定义格式化程序的行。这是设置中使用的 IEdmModel 函数:
private static IEdmModel GetEdmModel(IServiceProvider services)
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder(services);
builder.Namespace = "RS";
builder.EntitySet<PropertyIndexODataModel>("Properties");
builder.EntitySet<ReportResultModel>("Reports");
var function = builder.EntityType<ReportResultModel>().Collection.Function("Generate");
function.Parameter<int>("listId");
function.CollectionParameter<string>("functionsToRun");
function.ReturnsCollectionFromEntitySet<ReportResultModel>("Reports");
return builder.GetEdmModel();
}
因此,当我应用此 odataroute 时,我一直收到 404。当我删除它并返回 'endpoints.MapODataRoute("odata", "odata", GetEdmModel(app.ApplicationServices));' 时,它可以正常工作。
这似乎是一件非常微不足道的事情,但我到处搜索,仍然无法让它工作。我正在使用 OData 7.4 和 netcore 3.1。提前致谢!
我认为这里发生的是 MapODataRoute 缺少路由配置。尝试在 SmartODataSerializerProvider 注册后添加以下内容:
a.AddService<IEnumerable<IODataRoutingConvention>>(Microsoft.OData.ServiceLifetime.Singleton, sp =>
ODataRoutingConventions.CreateDefaultWithAttributeRouting("odata", endPoints.ServiceProvider));
我遇到了同样的问题,这为我解决了。有关详细信息,请参阅 this issue。
所以我正在构建一个必须通过 OData 使用的服务,我很难弄清楚如何向它添加自定义格式化程序。我需要我的 OData 序列化程序在序列化数据时忽略空值。我创建了这两个来实现这一点:
public class SmartODataSerializerProvider : DefaultODataSerializerProvider
{
private readonly SmartODataEntityTypeSerializer _entityTypeSerializer;
public SmartODataSerializerProvider(IServiceProvider rootContainer)
: base(rootContainer)
{
_entityTypeSerializer = new SmartODataEntityTypeSerializer(this);
}
public override ODataEdmTypeSerializer GetEdmTypeSerializer(Microsoft.OData.Edm.IEdmTypeReference edmType)
{
// Support for Entity types AND Complex types
if (edmType.Definition.TypeKind == EdmTypeKind.Entity || edmType.Definition.TypeKind == EdmTypeKind.Complex)
return _entityTypeSerializer;
else
return base.GetEdmTypeSerializer(edmType);
}
}
和
public class SmartODataEntityTypeSerializer : ODataResourceSerializer
{
public SmartODataEntityTypeSerializer(ODataSerializerProvider provider)
: base(provider) { }
/// <summary>
/// Only return properties that are not null
/// </summary>
/// <param name="structuralProperty">The EDM structural property being written.</param>
/// <param name="resourceContext">The context for the entity instance being written.</param>
/// <returns>The property be written by the serilizer, a null response will effectively skip this property.</returns>
public override Microsoft.OData.ODataProperty CreateStructuralProperty(Microsoft.OData.Edm.IEdmStructuralProperty structuralProperty, ResourceContext resourceContext)
{
var property = base.CreateStructuralProperty(structuralProperty, resourceContext);
return property.Value != null ? property : null;
}
}
这些是在另一个堆栈溢出问题上提供的。但是,当我尝试使用此序列化程序时出现问题。我已经有一个正在工作的 odata 端点(它只是用 null 序列化所有内容)并且当我将以下配置应用于它时,我不断在没有它的情况下工作的同一个 EP 上得到“404 Not Found”。
app.UseEndpoints(endpoints =>
{
endpoints.MapODataRoute("odata", "odata", a =>
{
a.AddService(Microsoft.OData.ServiceLifetime.Singleton, typeof(IEdmModel), sp => GetEdmModel(app.ApplicationServices));
a.AddService(Microsoft.OData.ServiceLifetime.Singleton, typeof(ODataSerializerProvider), sp => new SmartODataSerializerProvider(sp));
});
endpoints.EnableDependencyInjection();
//endpoints.MapODataRoute("odata", "odata", GetEdmModel(app.ApplicationServices));
endpoints.MapControllers();
});
这是端点设置。我注释掉了使它工作但没有自定义格式化程序的行。这是设置中使用的 IEdmModel 函数:
private static IEdmModel GetEdmModel(IServiceProvider services)
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder(services);
builder.Namespace = "RS";
builder.EntitySet<PropertyIndexODataModel>("Properties");
builder.EntitySet<ReportResultModel>("Reports");
var function = builder.EntityType<ReportResultModel>().Collection.Function("Generate");
function.Parameter<int>("listId");
function.CollectionParameter<string>("functionsToRun");
function.ReturnsCollectionFromEntitySet<ReportResultModel>("Reports");
return builder.GetEdmModel();
}
因此,当我应用此 odataroute 时,我一直收到 404。当我删除它并返回 'endpoints.MapODataRoute("odata", "odata", GetEdmModel(app.ApplicationServices));' 时,它可以正常工作。
这似乎是一件非常微不足道的事情,但我到处搜索,仍然无法让它工作。我正在使用 OData 7.4 和 netcore 3.1。提前致谢!
我认为这里发生的是 MapODataRoute 缺少路由配置。尝试在 SmartODataSerializerProvider 注册后添加以下内容:
a.AddService<IEnumerable<IODataRoutingConvention>>(Microsoft.OData.ServiceLifetime.Singleton, sp =>
ODataRoutingConventions.CreateDefaultWithAttributeRouting("odata", endPoints.ServiceProvider));
我遇到了同样的问题,这为我解决了。有关详细信息,请参阅 this issue。