ASP.NET Web Api OData v4 - 如何通过$ metadata反映小数和精度?

时间:2018-05-03 14:35:50

标签: c# asp.net asp.net-web-api odata

使用ASP.NET Web API 2.2 / OData v4.0是否可以在$ metadata端点中定义小数位数和精度?

目前我已经定义了一个包含许多小数属性的PricingModel.cs:

...
public decimal? PurchasePrice { get; set; }        
public decimal? SellingPrice { get; set; }
...

继承自ODataController的PricingController.cs和一个基本的实体数据模型在Startup.cs中定义:

public void Configuration(IAppBuilder appBuilder)
{
    var config = new HttpConfiguration();

    // Model builder
    ODataModelBuilder builder = new ODataConventionModelBuilder();
    builder.EntitySet<PricingModel>("Pricing");

    // Map route (Default)
    config.MapODataServiceRoute(
        routeName: "ODataRoute",
        routePrefix: null,
        model: builder.GetEdmModel());

    appBuilder.UseWebApi(config);
}

$元数据中反映的是(缺少比例和精度):

...    
<Property Name="PurchasePrice" Type="Edm.Decimal"/>
<Property Name="SellingPrice" Type="Edm.Decimal"/>
...

OData Version 4.0 Common Schema Definition应该允许将比例和精度包含在$ metadata中。

  

6.2.4属性比例

     

十进制属性可以为Scale属性定义非负整数值或变量。

     

此属性指定小数点右侧允许的最大位数。

     

值变量意味着小数点右边的位数可以从零到精度属性的值变化。

     

整数值表示小数点右边的位数可以从零到Scale属性的值变化,小数点左边的位数可以从1变化到值Precision属性减去Scale属性的值。如果Precision等于Scale,则单个零必须在小数点之前。

     

Scale属性的值必须小于或等于Precision属性的值。如果未指定任何值,则“缩放”构面默认为零。

     

注意:如果基础数据存储允许负标度,则服务可以使用Precision属性,负标度的绝对值添加到实际有效小数位数,并且客户提供的值可能必须在舍入之前进行舍入存储

     

示例9:应用于Decimal类型的精度和比例面。   允许值:1.23,0.23,3.14和0.7,不允许值:123,12.3。

     

<Property Name="Amount" Type="Edm.Decimal" Precision="3" Scale="2" />

     

示例10:精度等于比例。   允许值:0.23,0.7,不允许值:1.23,1.2。

     

<Property Name="Amount" Type="Edm.Decimal" Precision="2" Scale="2" />

     

示例11:应用于Decimal类型的Precision和变量Scale。   允许值:0.123,1.23,0.23,0.7,123和12.3,由于精度有限,不允许使用:12.34,1234和123.4。

     

<Property Name="Amount" Type="Edm.Decimal" Precision="3" Scale="variable" />

阅读Configure the OData Endpoint我明白我可能应该以某种方式通过ODataModelBuilder实例修改实体数据模型(EDM),但似乎无法找到解决方法。

  

EDM是数据的抽象模型。 EDM用于创建服务元数据文档。 ODataConventionModelBuilder类使用默认命名约定创建EDM。这种方法需要的代码最少。如果您想要更多地控制EDM,可以使用ODataModelBuilder类通过显式添加属性,键和导航属性来创建EDM。

1 个答案:

答案 0 :(得分:1)

以下代码可以解决这个问题,也许它可以帮助别人......

...
// Model builder
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<PricingModel>("Pricing");
builder.EntitySet<PricingModel>("Pricing").EntityType.Property(x => x.PurchasePrice).Precision = 19;
builder.EntitySet<PricingModel>("Pricing").EntityType.Property(x => x.PurchasePrice).Scale = 3;
...

现在这就是$元数据中的反映......

...
<Property Name="PurchasePrice" Type="Edm.Decimal" Precision="19" Scale="3"/>
...