1

URI で使用するすべての OData コマンドで、次のエラーが表示されます。
構成/パラメーター OData なしで API を使用すると、完全に機能します!
ただし、$filter$topまたは$skipは、以下のエラーを生成します。

コード

ApiController

[Queryable]
public IQueryable<Processo> get()
{
    return _repositorio.Query<Processo>();
}

API ルート

public static void Register(HttpConfiguration config)
{
    // Controller Only -> To handle routes like `/api/pessoas`
    config.Routes.MapHttpRoute(
        name: "ControllerOnly",
        routeTemplate: "api/{controller}"
    );

    // Controller with ID -> To handle routes like `/api/pessoas/1`
    config.Routes.MapHttpRoute(
        name: "ControllerAndId",
        routeTemplate: "api/{controller}/{id}",
        defaults: null,
        constraints: new { id = @"^\d+$" } // Only integers 
    );

    // Controllers with Actions -> To handle routes like `/api/pessoas/getProfissoes`
    config.Routes.MapHttpRoute(
        name: "ControllerAndAction",
        routeTemplate: "api/{controller}/{action}"
    );

    config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
    config.Formatters.Remove(config.Formatters.XmlFormatter);
}

IRepository クエリの実装

public IQueryable<T> Query<T>(params Expression<Func<T, object>>[] includeProperties)
    where T : class, IEntity
{
    return includeProperties.Aggregate<Expression<Func<T, object>>, IQueryable<T>>(Set<T>(), (current, includeProperty) => current.Include(includeProperty));
}

[追加] Processo クラス

public class Processo : IEntity, IAuditable
{
    public DateTime CreateAt { get; set; }
    public string CreateBy { get; set; }
    public DateTime? UpdateAt { get; set; }
    public string UpdateBy { get; set; }

    public int Id { get; set; }

    public DateTime DataEntrada { get; set; }
    public virtual Modalidade Modalidade { get; set; }
    public virtual PassoExecucao PassoAtual { get; set; }

    public string Imovel { get; set; }
    public double ValorFinanciado { get; set; }
    public double ValorVenda { get; set; }
    public double? FGTS { get; set; }

    public virtual Pessoa Comprador { get; set; }
    public virtual Pessoa Proprietario { get; set; }

    public virtual Agencia Agencia { get; set; }
    public virtual Empresa Despachante { get; set; }
    public virtual Empresa Originador { get; set; }

    public virtual ICollection<File> Arquivos { get; set; }
    public virtual ICollection<Historico> Historicos { get; set; }
}

試み

  1. URL:/api/processos?$filter=Id eq 1 同じエラー
  2. URL:/api/processos?$skip=1 同じエラー
  3. URL:/api/processos エラーなし!!

[追加] いくつかのテストを行っています。Person クラスへの参照がある場合にのみ発生することがわかりました。

public class Pessoa : IEntity, IAuditable
{
    public int Id { get; set; }

    public DateTime CreateAt { get; set; }
    public string CreateBy { get; set; }
    public DateTime? UpdateAt { get; set; }
    public string UpdateBy { get; set; }

    public string Nome { get; set; }
    public DateTime? DataNascimento { get; set; }
    public GeneroEnum Genero { get; set; }
    public virtual TipoPessoa Tipo { get; set; }
    public virtual Pessoa Conjuge { get; set; }

    public virtual Nacionalidade Nacionalidade { get; set; }
    public string Naturalidade { get; set; }
    public virtual Profissao Profissao { get; set; }
    public string Empresa { get; set; }
    public double? RendaBrutaMensal { get; set; }
    public DateTime? DataInicioEmpresa { get; set; }
    public DateTime? DataReferenciaEmpresa { get; set; }
    public EscolaridadeEnum Escolaridade { get; set; }

    public string CPF { get; set; }
    public string PIS { get; set; }
    public string RG { get; set; }
    public string OrgaoExpedidor { get; set; }
    public string TipoDocumento { get; set; }
    public DateTime? DataEmissao { get; set; }

    public EstadoCivilEnum? EstadoCivil { get; set; }
    public RegimeCasamentoEnum? RegimeCasamento { get; set; }
    public bool? ComposicaoRenda { get; set; }
    public bool? UniaoEstavel { get; set; }

    public virtual ICollection<Telefone> Telefones { get; set; }
    public virtual ICollection<Endereco> Enderecos { get; set; }
    public virtual ICollection<Email> Emails { get; set; }
}

エラー

Processo クラスあり

[Queryable]
public IQueryable<Processo> get()
{
    return _repositorio.Query<Processo>();
}

ここに画像の説明を入力

{
    "$id": "1",
    "Message": "An error has occurred.",
    "ExceptionMessage": "The property does not belong to the specified type.\r\nParameter name: navigationProperty",
    "ExceptionType": "System.ArgumentException",
    "StackTrace": "   at System.Web.Http.OData.Builder.EntityTypeConfiguration.AddNavigationProperty(PropertyInfo navigationProperty, EdmMultiplicity multiplicity)\r\n   at System.Web.Http.OData.Builder.ODataConventionModelBuilder.MapEntityType(IEntityTypeConfiguration entity)\r\n   at System.Web.Http.OData.Builder.ODataConventionModelBuilder.AddEntity(Type type)\r\n   at System.Web.Http.OData.Builder.EntityTypeConfiguration.AddNavigationProperty(PropertyInfo navigationProperty, EdmMultiplicity multiplicity)\r\n   at System.Web.Http.OData.Builder.ODataConventionModelBuilder.MapEntityType(IEntityTypeConfiguration entity)\r\n   at System.Web.Http.OData.Builder.ODataConventionModelBuilder.MapTypes()\r\n   at System.Web.Http.OData.Builder.ODataConventionModelBuilder.GetEdmModel()\r\n   at System.Web.Http.HttpActionDescriptorExtensions.<>c__DisplayClass1.<GetEdmModel>b__0(Object _)\r\n   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)\r\n   at System.Web.Http.HttpActionDescriptorExtensions.GetEdmModel(HttpActionDescriptor actionDescriptor, Type entityClrType)\r\n   at System.Web.Http.QueryableAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)\r\n   at System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecuted(HttpActionContext actionContext, HttpResponseMessage response, Exception exception)\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<>c__DisplayClass2.<System.Web.Http.Filters.IActionFilter.ExecuteActionFilterAsync>b__0(HttpResponseMessage response)\r\n   at System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass41`2.<Then>b__40(Task`1 t)\r\n   at System.Threading.Tasks.TaskHelpersExtensions.ThenImpl[TTask,TOuterResult](TTask task, Func`2 continuation, CancellationToken cancellationToken, Boolean runSynchronously)"
}

ペソアクラスで

[Queryable]
public IQueryable<Pessoa> get()
{
    return _repositorio.Query<Pessoa>();
}


{
    "$id": "1",
    "Message": "An error has occurred.",
    "ExceptionMessage": "An item with the same key has already been added.",
    "ExceptionType": "System.ArgumentException",
    "StackTrace": "   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)\r\n   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)\r\n   at System.Web.Http.OData.Builder.EdmTypeBuilder.<GetEdmTypes>d__0.MoveNext()\r\n   at System.Linq.Enumerable.<OfTypeIterator>d__aa`1.MoveNext()\r\n   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)\r\n   at System.Web.Http.OData.Builder.EdmModelHelperMethods.BuildEdmModel(String containerNamespace, String containerName, IEnumerable`1 entityTypeConfigurations, IEnumerable`1 entitySetConfigurations)\r\n   at System.Web.Http.OData.Builder.ODataModelBuilder.GetEdmModel()\r\n   at System.Web.Http.OData.Builder.ODataConventionModelBuilder.GetEdmModel()\r\n   at System.Web.Http.HttpActionDescriptorExtensions.<>c__DisplayClass1.<GetEdmModel>b__0(Object _)\r\n   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)\r\n   at System.Web.Http.HttpActionDescriptorExtensions.GetEdmModel(HttpActionDescriptor actionDescriptor, Type entityClrType)\r\n   at System.Web.Http.QueryableAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)\r\n   at System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecuted(HttpActionContext actionContext, HttpResponseMessage response, Exception exception)\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<>c__DisplayClass2.<System.Web.Http.Filters.IActionFilter.ExecuteActionFilterAsync>b__0(HttpResponseMessage response)\r\n   at System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass41`2.<Then>b__40(Task`1 t)\r\n   at System.Threading.Tasks.TaskHelpersExtensions.ThenImpl[TTask,TOuterResult](TTask task, Func`2 continuation, CancellationToken cancellationToken, Boolean runSynchronously)"
}
4

2 に答える 2

1

この回答は、チャットで発生したことの要約です。したがって、標準的な回答とは異なるタッチを読み取ります。


このエラーは特に発生していませんが、OData が「id」プロパティを見つけるのに問題があるようです。oData がスタンドアロン パッケージに取り出されると、いくつかの変更がありました。

バージョン?
最初に確認することは、スタンドアロンの oData パッケージ (Microsoft.Data.OData 5.0.1およびMicrosoft.AspNet.WebApi.OData 0.1.0-alpha-120815) があるかどうかです。Get-Packageこれを行うには、パッケージ管理コンソールに入力します。

チャットでこれらを投稿しました:

Microsoft.AspNet.WebApi.OData 0.1.0-alpha-120815
Microsoft.Data.Edm 5.1.0-rc2
Microsoft.Data.OData 5.1.0-rc2
Microsoft.Data.OData.Contrib 5.1.0.50918-rc
System.Spatial 5.1 .0-rc2

そのため、まだ製品の RC を実行しているようです。この動作を説明していると思われる古いバグがあります。バグの短所は、継承されたプロパティを持つクラスがエラーをスローすることです。

現在はうまく
いかない 現在のバージョンにアップデートしても問題は解決しないようです。したがって、次のステップは、新しい署名付きナイトリーを試すことです。

署名付きナイトリー ビルドを取得する手順は、こちら.

署名された夜間ビルドは問題を解決しました。

別の考え

oData の変更後、製品はキー プロパティを識別できる必要があります。 この記事では次のように述べています

どういうわけか、[Queryable] 属性はキー プロパティを見つけなければなりません。要素タイプに ID プロパティがある場合、これは自動的に行われます。そうでない場合は、モデルを手動で構成する必要がある場合があります (モデルの設定を参照)。

Entity Framework を使用している場合、人物オブジェクトにはエンティティ キーが定義されていますか? そうでない場合は、oDataConventionModelBuilder「モデルのセットアップ」セクションで指定されている方法を試していただけますか。何かのようなもの:

ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
var pessoa= modelBuilder.EntitySet<Pessoa>("Pessoa"); 

 pessoa..HasKey(p => p.Id); 
 ...
于 2012-10-17T19:47:51.110 に答える
0

OData では、Pessoa クラスの主キーの概念を指定する必要があります。属性を追加してこれを行うか:

[DataServiceKey("Id")]
public class Pessoa : IEntity, IAuditable
{
    public int Id { get; set; }
    //...
}

または、OData Web API リリースのブログ記事http://blogs.msdn.com/b/alexj/archive/2012/08/15/odata-support-in-asp-netに記載されているように、キーを指定してモデルを明示的に構築します。-web-api.aspx「モデルのセットアップ」見出しセクション。

于 2012-10-17T19:56:33.747 に答える