OData无法识别我的收藏夹属性 [英] OData Doesn't Recognize My Collection Properties

查看:63
本文介绍了OData无法识别我的收藏夹属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我发布的ShakeoutDocument中没有填充集合时,OData Serializer会理解JSON&正确填充ODataActionParameters.

When I post a ShakeoutDocument without the collections populated, the OData Serializer understands the JSON & populates the ODataActionParameters correctly.

但是,当我将子记录添加到任一ShakeoutDocument's集合属性中时,Odata Controller's ODataActionParameters参数为空.我将其范围缩小到了OData EDM Model Configuration.

However, when I add a child-record into either of the ShakeoutDocument's collection properties...the Odata Controller's ODataActionParameters parameter is null. I have narrowed it down to the OData EDM Model Configuration.

  • 如何正确地将收集"属性(如下所示)表征"到EDM模型配置中

喜欢的班级:
这些集合是详细信息"和封条(下)

THE CLASS LOOKS LIKE:
The collections are the Details & Seals (below)

public class ShakeoutDocument : Document
{
    public IObjectState ObjectState { get; set; } //<-- This "registers" just fine?

    public int ShakeoutId { get; set; }

    public string SchedulingBatch { get; set; }

    public int? ProductId { get; set; }

    public decimal? Gravity { get; set; }

    public decimal? Temperature { get; set; }

    public decimal? SedimentAndWater { get; set; }

    public DateTime? BatchEndDate { get; set; }

    public DateTime? SampleWorkedDate { get; set; }

    public string Witness { get; set; }

    public string Notes { get; set; }

    public List<ShakeoutDetail> Details { get; set; } //<-- How do I "register" this?

    public List<ShakeoutSeal> Seals { get; set; } //<-- How do I "register" this?
}

我当前的EDM配置外观如下:
我尝试了定义为 HERE 的各种方法.奇怪的是... IObjectState注册就好了.

MY CURRENT EDM CONFIGURATION LOOKS LIKE:
I have tried various approaches as defined HERE. The odd thing is...IObjectState registers just fine.

private static  IEdmModel GetEdmModel()
{
    var modelBuilder = new ODataConventionModelBuilder();
    modelBuilder.Namespace = "Pulse";
    modelBuilder.ContainerName = "PulseContainer";

    // -------------------
    // ENTITY SETS: Normal
    modelBuilder.EntitySet<tblDbcCommunications>("Communication");
    modelBuilder.EntitySet<tblDbcItems>("Item");
    modelBuilder.EntitySet<Meter>("Meter");
    modelBuilder.EntitySet<Product>("Products");
    modelBuilder.EntitySet<WarehouseMeter>("WarehouseMeters");
    modelBuilder.EntitySet<tblDbcCircuitOwner>("tblDbcCircuitOwner");
    modelBuilder.EntitySet<ShakeoutDetail>("ShakeoutDetails");
    modelBuilder.EntitySet<ShakeoutSeal>("ShakeoutSeals");

    // --------------------
    // ENTITY SETS: Complicated
    ConfigureEntitySet(modelBuilder, modelBuilder.EntitySet<ShakeoutDocument>("ShakeoutDocuments"));

    // ------------
    // KEY BINDINGS: Non-Entity
    //
    // - This area is for DTO's (there is no EF Configuration for these)
    modelBuilder.EntityType<WarehouseMeter>().HasKey(x => x.METER_ID);

    // -----------------
    // UNBOUND FUNCTIONS
    //  - Action    = Post
    //  - Function  = Get

    //----
    // ShakeoutDocument
    var createShakeoutDocument = modelBuilder.Action("CreateShakeoutDocument").ReturnsFromEntitySet<ShakeoutDocument>("ShakeoutDocument");
    createShakeoutDocument.CollectionParameter<int>("identities");

    var deleteShakeoutDocument = modelBuilder.Action("DeleteShakeoutDocument").ReturnsFromEntitySet<ShakeoutDocument>("ShakeoutDocument");
    deleteShakeoutDocument.Parameter<int>("key");

    var getShakeoutDocument = modelBuilder.Function("GetShakeoutDocument").ReturnsFromEntitySet<ShakeoutDocument>("ShakeoutDocument");
    getShakeoutDocument.Parameter<int>("key");

    var saveShakeoutDocument = modelBuilder.Action("SaveShakeoutDocument").ReturnsFromEntitySet<ShakeoutDocument>("ShakeoutDocument");
    saveShakeoutDocument.Parameter<ShakeoutDocument>("document");

    //----
    // ShakeoutDetail
    var saveShakeoutDetail = modelBuilder.Action("SaveShakeoutDetail").ReturnsFromEntitySet<ShakeoutDetail>("ShakeoutDetail");
    saveShakeoutDetail.Parameter<ShakeoutDetail>("detail");

    //----
    // ShakeoutSeal
    var saveShakeoutSeal = modelBuilder.Action("SaveShakeoutSeal").ReturnsFromEntitySet<ShakeoutSeal>("ShakeoutSeal");
    saveShakeoutSeal.Parameter<ShakeoutSeal>("seal");

    //----
    // Product
    var listProduct = modelBuilder.Function("ListProducts").ReturnsCollectionFromEntitySet<Product>("Product");

    //----
    // WarehouseMeter
    var findPulseMeter = modelBuilder.Function("FindWarehouseMeter").ReturnsCollectionFromEntitySet<WarehouseMeter>("WarehouseMeter");
    findPulseMeter.Parameter<string>("search");

    return modelBuilder.GetEdmModel();
}

private static EntitySetConfiguration<ShakeoutDocument> ConfigureEntitySet(ODataConventionModelBuilder modelBuilder, EntitySetConfiguration<ShakeoutDocument> configuration)
{
    // ---------------------
    // Collection Properties

    // FAILS: Meaning, the collection is not serialized & returned
    //var details = configuration.EntityType.CollectionProperty(x => x.Details);
    //var seals = configuration.EntityType.CollectionProperty(x => x.Seals);

    // FAILS: Meaning, the collection is not serialized & returned
    //configuration.HasManyBinding(x => x.Details, "ShakeoutDetail");
    //configuration.HasManyBinding(x => x.Seals, "ShakeoutSeal");

    // ------------------
    // Complex Properties
    configuration.EntityType.ComplexProperty(x => x.ObjectState);

    // IObjectState
    var objectState = modelBuilder.ComplexType<IObjectState>();
    objectState.CollectionProperty(x => x.Events);

    // Object State
    var newObjectState = modelBuilder.ComplexType<New>();
    newObjectState.DerivesFrom<IObjectState>();

    var submittedObjectState = modelBuilder.ComplexType<Submitted>();
    submittedObjectState.DerivesFrom<IObjectState>();

    // Object State Event
    var isNewObjectStateEvent = modelBuilder.ComplexType<IsNew>();
    isNewObjectStateEvent.DerivesFrom<IObjectStateEvent>();

    var isSubmittedObjectStateEvent = modelBuilder.ComplexType<IsSubmitted>();
    isSubmittedObjectStateEvent.DerivesFrom<IObjectStateEvent>();

    return configuration;
}

发送此JSON作品:
如果我SEND,则此JSON无需填充详细信息"和"Seals collections..it正确序列化.

SENDING THIS JSON WORKS:
If I SEND this JSON WITHOUT populating the Details & Seals collections..it serializes correctly.

如果我填充详细信息"和密封收集...参数为NULL.

If I populate the Details & Seals collections...the parameter is NULL.

{
    "DocumentTypeId": 1,
    "GlobalId": "e8c9d71d-2773-e911-b71a-8cdcd4471a95",
    "ParentId": null,
    "AuthorId": 1,
    "PublisherId": null,
    "RevisionNumber": 0,
    "PublishedDate": null,
    "IsActive": true,
    "Id": 44,
    "CreateUserId": "(removed)",
    "CreateDate": "2019-05-10T08:25:46.31-05:00",
    "UpdateUserId": "(removed)",
    "UpdateDate": "2019-05-10T08:25:46.31-05:00",
    "ShakeoutId": 44,
    "SchedulingBatch": null,
    "ProductId": null,
    "Gravity": null,
    "Temperature": null,
    "SedimentAndWater": null,
    "BatchEndDate": null,
    "SampleWorkedDate": null,
    "Witness": null,
    "Notes": null,
    "Seals": [],
    "Details": [],
    "ObjectState": {
        "@odata.type": "#Namespace...ShakeoutDocument.New",
        "Name": "New",
        "Events": [
            {
                "@odata.type": "#Namespace...ShakeoutDocument.IsNew",
                "Name": "IsNew"
            }
        ]
    }
}

接收失败:
这显示了从服务和发送回客户端的对象.客户端收到的JSON.

RECEIVING FAILS:
This shows the object sent BACK TO the Client FROM the Service & the JSON received by the Client.

无限功能外观:
为了完整起见,我包括了...

THE UNBOUND FUNCTION LOOKS LIKE:
For completeness, I am including this...

[HttpPost]
[ODataRoute("SaveShakeoutDocument")]
public IHttpActionResult SaveDocument(ODataActionParameters parameters)
{
    var provider = Application.ShakeoutDocumentProvider;
    var document = null as ShakeoutDocument;

    try
    {
        document = provider.Get(key);
    }
    catch (Exception ex)
    {
        LogException(ex);

        throw;
    }

    return Ok(document);
}

更新1:
$ MetaData似乎了解收集类型...

UPDATE 1:
The $MetaData seems to understand the collection types...

<EntityType Name="ShakeoutDocument" BaseType="Pulse.Document">
    <Property Name="ObjectState" Type="Pulse.IObjectState" Nullable="false"/>
    <Property Name="ShakeoutId" Type="Edm.Int32" Nullable="false"/>
    <Property Name="SchedulingBatch" Type="Edm.String"/>
    <Property Name="ProductId" Type="Edm.Int32"/>
    <Property Name="Gravity" Type="Edm.Decimal"/>
    <Property Name="Temperature" Type="Edm.Decimal"/>
    <Property Name="SedimentAndWater" Type="Edm.Decimal"/>
    <Property Name="BatchEndDate" Type="Edm.DateTimeOffset"/>
    <Property Name="SampleWorkedDate" Type="Edm.DateTimeOffset"/>
    <Property Name="Witness" Type="Edm.String"/>
    <Property Name="Notes" Type="Edm.String"/>
    <NavigationProperty Name="Details" Type="Collection(Pulse.ShakeoutDetail)"/>
    <NavigationProperty Name="Seals" Type="Collection(Pulse.ShakeoutSeal)"/>
</EntityType>

更新2:
我刚刚注意到... ShakeoutDetails& ShakeoutDetail的NavigationPropertyBinding为"Meter" ...在ShakeoutDocument中不存在(并且由于它不是实体,所以不会包含在内).

UPDATE 2:
I just noticed...ShakeoutDetails & ShakeoutDetail have a NavigationPropertyBinding of "Meter"...which is not present in ShakeoutDocument (and never will be included as this is a Model not an Entity).

<?xml version="1.0" encoding="UTF-8"?>
<EntityContainer Name="PulseContainer">
   <EntitySet Name="Communication" EntityType="Pulse.tblDbcCommunications" />
   <EntitySet Name="Item" EntityType="Pulse.tblDbcItems" />
   <EntitySet Name="Meter" EntityType="Pulse.Meter" />
   <EntitySet Name="Products" EntityType="Pulse.Product" />
   <EntitySet Name="WarehouseMeters" EntityType="Pulse.WarehouseMeter" />
   <EntitySet Name="tblDbcCircuitOwner" EntityType="Pulse.tblDbcCircuitOwner" />
   <EntitySet Name="ShakeoutDetails" EntityType="Pulse.ShakeoutDetail">
      <NavigationPropertyBinding Path="Meter" Target="Meter" />
   </EntitySet>
   <EntitySet Name="ShakeoutSeals" EntityType="Pulse.ShakeoutSeal" />
   <EntitySet Name="ShakeoutDocuments" EntityType="Pulse.ShakeoutDocument" />
   <EntitySet Name="ShakeoutDocument" EntityType="Pulse.ShakeoutDocument" />
   <EntitySet Name="ShakeoutDetail" EntityType="Pulse.ShakeoutDetail">
      <NavigationPropertyBinding Path="Meter" Target="Meter" />
   </EntitySet>
   <EntitySet Name="ShakeoutSeal" EntityType="Pulse.ShakeoutSeal" />
   <EntitySet Name="Product" EntityType="Pulse.Product" />
   <EntitySet Name="WarehouseMeter" EntityType="Pulse.WarehouseMeter" />
   <ActionImport Name="CreateShakeoutDocument" Action="Pulse.CreateShakeoutDocument" EntitySet="ShakeoutDocument" />
   <ActionImport Name="DeleteShakeoutDocument" Action="Pulse.DeleteShakeoutDocument" EntitySet="ShakeoutDocument" />
   <FunctionImport Name="GetShakeoutDocument" Function="Pulse.GetShakeoutDocument" EntitySet="ShakeoutDocument" IncludeInServiceDocument="true" />
   <ActionImport Name="SaveShakeoutDocument" Action="Pulse.SaveShakeoutDocument" EntitySet="ShakeoutDocument" />
   <ActionImport Name="SaveShakeoutDetail" Action="Pulse.SaveShakeoutDetail" EntitySet="ShakeoutDetail" />
   <ActionImport Name="SaveShakeoutSeal" Action="Pulse.SaveShakeoutSeal" EntitySet="ShakeoutSeal" />
   <FunctionImport Name="ListProducts" Function="Pulse.ListProducts" EntitySet="Product" IncludeInServiceDocument="true" />
   <FunctionImport Name="FindWarehouseMeter" Function="Pulse.FindWarehouseMeter" EntitySet="WarehouseMeter" IncludeInServiceDocument="true" />
</EntityContainer>

推荐答案

根据您的上一次更新,我认为导航属性绑定很有趣.

In according your last update i think problem interesting with navigation property binding.

它不能解决仪表问题,您应该查看 https://odata. github.io/WebApi/13-03-NavigationPropertyBindingWithComplexType/ (如果需要,还可以查看瞬态操作")

It does not resolve Meter, you should look that https://odata.github.io/WebApi/13-03-NavigationPropertyBindingWithComplexType/ (Also look Transient Actions, if you needed)

这篇关于OData无法识别我的收藏夹属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆