如何使用 System.Web.OData (asp.net) 控制 json 格式

Dan*_*ele 0 c# asp.net json odata

这是我的情况:

我正在使用 OData 开发一个 asp.net web api 项目。我正在使用 Microsoft.Aspnet.OData NuGet 包。

我的目的是在构建响应时拦截到 json 的序列化。

使用 System.Web.OData,我试图扩展 System.Web.OData.Formatter.Serialization.DefaultODataSerializerProvider:

public class MyODataSerializerProvider : DefaultODataSerializerProvider
{

    public MyODataSerializerProvider(IServiceProvider rootContainer) : base(rootContainer)
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

然后,在我的 WebApiConfig.Register 方法中,我想执行以下操作:

config.Formatters.InsertRange(0, ODataMediaTypeFormatters.Create(new MyODataSerializerProvider(???), new DefaultODataDeserializerProvider(???)));
Run Code Online (Sandbox Code Playgroud)

我放在哪里???上面是问题:在 System.Web.OData(版本 6.0.0.0)的最后一次更新中,他们添加了对依赖注入的支持,但我不知道将什么作为 rootContainer 参数传递。

我读过这个:http : //odata.github.io/odata.net/v7/#01-05-di-support 但我不需要创建我的容器构建器(至少我是这么认为的),我只想使用我认为 OData 准备的 IServiceProvider。我对吗?我可以检索这个 IServiceProvider 并将它传递给我的构造函数吗?

一个更普遍的问题是,我正在尝试以正确的方式满足我的需求,即能够控制响应的序列化?

情况示例:假设响应是实体类型“Customer”的集合,其属性之一名为 int 类型的“Prop”。当为某个特定用户构建此集合时,我想屏蔽“Prop”的实际值并改为写入“Prop”:0。

我们尝试了其他方式通过代码来实现这一点,但我认为对于我们的需求最好的解决方案是能够控制json序列化。

谢谢。

bam*_*bam 5

我今天遇到了同样的问题。您按照此示例注册 MyODataSerializerProvider:

    public void Register(HttpConfiguration config)
    {
        config.MapODataServiceRoute
        (
            "odata",
            "odata",
            BuildRoute
        );
    }

    private void BuildRoute(IContainerBuilder builder)
    {
        builder
            .AddService(ServiceLifetime.Singleton, s => BuildEdmModelForOData())
            .AddService<ODataSerializerProvider>(ServiceLifetime.Singleton, s => new MyODataSerializerProvider(s));
    }

    public IEdmModel BuildEdmModelForOData()
    {
        ODataConventionModelBuilder
            builder = new ODataConventionModelBuilder();

        // Build model here

        return builder.GetEdmModel();
    }
Run Code Online (Sandbox Code Playgroud)

关于您更一般的问题,可以像这样拦截和替换对象值:

class MyODataSerializerProvider : DefaultODataSerializerProvider
{
    public MyODataSerializerProvider(IServiceProvider rootContainer)
        : base(rootContainer)
    {
    }

    public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
    {
        if (edmType.Definition.TypeKind == EdmTypeKind.Entity)
            return new MyODataResourceSerializer(this);
        else
            return base.GetEdmTypeSerializer(edmType);
    }
}

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

    public override ODataProperty CreateStructuralProperty(IEdmStructuralProperty structuralProperty, ResourceContext resourceContext)
    {
        ODataProperty
            property = base.CreateStructuralProperty(structuralProperty, resourceContext);

        if (resourceContext.StructuredType.FullTypeName() == typeof(Customer).FullName)
        {
            switch (property.Name)
            {
                case "Prop":
                    property.Value = 0;
                    break;
            }
        }

        return property;
    }
}
Run Code Online (Sandbox Code Playgroud)

还值得一提的是,从 CreateStructuralProperty 返回 null 会完全抑制该属性。

希望这仍然有帮助。