OData 会忽略某些属性,除非明确声明要返回

发布于 2025-01-12 19:12:32 字数 435 浏览 1 评论 0原文

我的这个模型具有以下属性。 (简化)

public class Blog {
   private string Code { get; set; }
   private string Name { get; set; }
   private byte[] Image { get; set; }
}

当我向 OData URL 发出请求时,例如:http://localhost/api/odata/Blog,我只想返回 Code 和 Name 属性,而忽略图像。如果我做 像 http://localhost/api/odata/Blog?$select=(Code,Name,Image) 这样的请求然后我希望返回图像。我怎样才能做到这一点? 使用 [IgnoreDataMember] 等属性会使 OData 查询无法访问,因此这不是一个合适的解决方案。

I have this model with following attributes. (Simplified)

public class Blog {
   private string Code { get; set; }
   private string Name { get; set; }
   private byte[] Image { get; set; }
}

When I make a request to the OData URL for ex: http://localhost/api/odata/Blog, I want only Code and Name properties to be returned, ignoring the Image. And if I make
a request something like http://localhost/api/odata/Blog?$select=(Code,Name,Image) then I want the Image to be returned. How can I make this work?
Using attributes like [IgnoreDataMember] makes it unavailable for OData query to be accessed, therefore it is not a suitable solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情丝乱 2025-01-19 19:12:32

首先,Blog 类的属性可能是公共的,而不是私有的。
我有一个类似的场景并通过实现自定义序列化器来解决它:
序列化器提供程序类:

public class MyODataSerializerProvider : DefaultODataSerializerProvider
{
    MyResourceSerializer myResourceSerializer;
    public MyODataSerializerProvider(IServiceProvider serviceProvider) : base(serviceProvider)
    {
        myResourceSerializer = new MyResourceSerializer(this);
    }

    public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
    {
        if (edmType.IsEntity())
        {
            return myResourceSerializer;
        }
        return base.GetEdmTypeSerializer(edmType);
    }
}

序列化器类:

public class MyResourceSerializer : ODataResourceSerializer
{
    public MyResourceSerializer(ODataSerializerProvider serializerProvider) : base(serializerProvider) { }

    public override ODataResource CreateResource(SelectExpandNode selectExpandNode, ResourceContext resourceContext)
    {
        var resource = base.CreateResource(selectExpandNode, resourceContext);
        if (selectExpandNode.SelectAllDynamicProperties)
        {
            resource.Properties = resource.Properties.Where(p => p.Name != "Image");
        }
        return resource;
    }
}

当然配置:

routeBuilder.MapODataServiceRoute("OData", "odata", b =>
                {
                    b.AddService(Microsoft.OData.ServiceLifetime.Singleton, sp => edmModel);
                    var conventions = ODataRoutingConventions.CreateDefault();
                    //Workaround for https://github.com/OData/WebApi/issues/1622
                    conventions.Insert(0, new AttributeRoutingConvention("OData", app.ApplicationServices, new DefaultODataPathHandler()));
                    //Custom Convention
                    b.AddService<IEnumerable<IODataRoutingConvention>>(Microsoft.OData.ServiceLifetime.Singleton, a => conventions);
                    b.AddService(Microsoft.OData.ServiceLifetime.Singleton, typeof(ODataSerializerProvider), sp => new MyODataSerializerProvider(sp));
                });

First, probably properties of the Blog class are public, not private.
I had a similar scenario and resolve it by implementing a custom serializer:
Serializer provider class:

public class MyODataSerializerProvider : DefaultODataSerializerProvider
{
    MyResourceSerializer myResourceSerializer;
    public MyODataSerializerProvider(IServiceProvider serviceProvider) : base(serviceProvider)
    {
        myResourceSerializer = new MyResourceSerializer(this);
    }

    public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
    {
        if (edmType.IsEntity())
        {
            return myResourceSerializer;
        }
        return base.GetEdmTypeSerializer(edmType);
    }
}

Serializer class:

public class MyResourceSerializer : ODataResourceSerializer
{
    public MyResourceSerializer(ODataSerializerProvider serializerProvider) : base(serializerProvider) { }

    public override ODataResource CreateResource(SelectExpandNode selectExpandNode, ResourceContext resourceContext)
    {
        var resource = base.CreateResource(selectExpandNode, resourceContext);
        if (selectExpandNode.SelectAllDynamicProperties)
        {
            resource.Properties = resource.Properties.Where(p => p.Name != "Image");
        }
        return resource;
    }
}

And configuration of course:

routeBuilder.MapODataServiceRoute("OData", "odata", b =>
                {
                    b.AddService(Microsoft.OData.ServiceLifetime.Singleton, sp => edmModel);
                    var conventions = ODataRoutingConventions.CreateDefault();
                    //Workaround for https://github.com/OData/WebApi/issues/1622
                    conventions.Insert(0, new AttributeRoutingConvention("OData", app.ApplicationServices, new DefaultODataPathHandler()));
                    //Custom Convention
                    b.AddService<IEnumerable<IODataRoutingConvention>>(Microsoft.OData.ServiceLifetime.Singleton, a => conventions);
                    b.AddService(Microsoft.OData.ServiceLifetime.Singleton, typeof(ODataSerializerProvider), sp => new MyODataSerializerProvider(sp));
                });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文