在Microsoft.AspNet.OData中考虑复杂类型和属性

时间:2019-05-07 13:43:07

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

我很难让一个复杂的对象进行序列化。我发现了一些例子,需要帮助。我有一个POCO类,为类属性实现一个接口,如下所示...

  • 问题是... OData无法序列化 IObjectState 属性

如何在属性中进行ODATA复杂类型的查询?

  • 请记住,IObjectState是非实体类,并且没有键

POCO类别:

                try {
                  final HttpsCallableResult result = await callable.call(
                    <String, dynamic>{
                      'message': 'hello world!',
                      'count': _responseCount,
                    },
                  );
                  print(result.data);
                  setState(() {
                    _response = result.data['repeat_message'];
                    _responseCount = result.data['repeat_count'];
                  });
                } on CloudFunctionsException catch (e) {
                  print('caught firebase functions exception');
                  print(e.code);
                  print(e.message);
                  print(e.details);
                } catch (e) {
                  print('caught generic exception');
                  print(e);
                }

IObjectState属性CLASS:
这是一个具体的IObjectState类的示例...

public class ShakeoutDocument : Document, IDocument, IStateful
{
    public IObjectState ObjectState { get; set; } //<-- This property contains the instance (below)

    public int ShakeoutId { get; set; }

    public string SchedulingBatch { get; set; }

    [...] //<-- Other properties are omitted for brevity
}

EDM配置:作为绑定功能:
使用此EDM模型配置和Api ...

// Example of an IObjectState Instance
public class New : IObjectState
{
    public List<IObjectStateEvent> Events { get; set; }

    public string Name { get; set; }
}

生成以下异常...

  

“给定的模型不包含类型'New'。”

EDM配置:作为取消绑定功能:
使用此EDM模型配置和Api ...

modelBuilder.EntitySet<ShakeoutDocument>("ShakeoutDocument");

[HttpGet]
public ShakeoutDocument Get([FromODataUri] int id)
{
    var provider = Application.ShakeoutDocumentProvider as ShakeoutDocumentProvider;
    var entity = provider.Get(id);

    return entity;
}

生成以下异常...

  

“给定的模型不包含类型'New'。”

更新EDM配置:使用具体的新功能
正在更新EDM模型配置...

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

[ODataRoute("GetShakeoutDocument(id={id})")]
public IHttpActionResult GetShakeoutDocument([FromODataUri] int id)
{
    var provider = Application.ShakeoutDocumentProvider as ShakeoutDocumentProvider;
    var entity = provider.Get(id);

    return Ok(entity);
}

生成以下异常...

  

”遇到了一个类型名称不兼容的值   与元数据。该值将其类型指定为“新建”,但类型   元数据中指定的是“ IObjectState”。”

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

好的,经过大量搜索,我找到了答案here。基本上,您必须向OData描述任何给定复杂属性的所有可能实现...甚至对于UNBOUND FUNCTIONS。

实际上没有绑定 SHOULD 意味着正在使用标准的WebApi ...但这显然不是这种情况。...因为该对象使用标准的WebApi对FINE进行了序列化,但使用OData却失败了。 >

private static  IEdmModel GetEdmModel()
{
    var modelBuilder = new ODataConventionModelBuilder();

    // ENTITY SETS: Normal
    modelBuilder.EntitySet<tblDbcCommunications>("Communication");
    modelBuilder.EntitySet<tblDbcItems>("Item");
    modelBuilder.EntitySet<Meter>("Meter");
    modelBuilder.EntitySet<Product>("Product");
    modelBuilder.EntitySet<WarehouseMeter>("WarehouseMeter");
    modelBuilder.EntitySet<Shakeout>("Shakeout");
    modelBuilder.EntitySet<tblDbcCircuitOwner>("tblDbcCircuitOwner");

    // ENTITY SETS: Complex
    ConfigureComplexEntitySet(modelBuilder, modelBuilder.EntitySet<ShakeoutDocument>("ShakeoutDocument"));

    // KEY BINDINGS
    modelBuilder.EntityType<WarehouseMeter>().HasKey(x => x.METER_ID);

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

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

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

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

    return modelBuilder.GetEdmModel();
}

private static EntitySetConfiguration<ShakeoutDocument> ConfigureComplexEntitySet(ODataConventionModelBuilder modelBuilder, EntitySetConfiguration<ShakeoutDocument> configuration)
{

    // Collection Properties
    configuration.EntityType.CollectionProperty(x => x.Seals);
    configuration.EntityType.CollectionProperty(x => x.Details);

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

    // 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;
}