microsoft / microsoft/OpenAPI.NET.OData

IEdmModel.ConvertToOpenApi() throws System.InvalidOperationException when having dollar-count similar path in controller

オープン 初心者向け
#661 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

主要言語
C#
スター
240
フォーク
70
平均マージ
7時間 59分
マージ済み PR(30日)
13

説明

I have a Count() operation in an ODataController. When I call ConvertToOpenApi on the IEdmModel a System.InvalidOperationException: 'Collection was modified; enumeration operation may not execute.' is thrown ( in src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs).

Assemblies affected

occurs at least in:

  • Microsoft.OpenApi.OData 1.7.4
  • Microsoft.OpenApi.OData 2.0.0 preview 8
Steps to reproduce

In an ODataController, add a dollar-count-similar operation, eg:

[HttpGet]
[Description("Shows the total count of entities")]
public async Task<IActionResult> Count()
{
    return await CountEntities();
}

Add the function to the ODataConventionModelBuilder, eg:
builder.EntityType<Entity>().Collection.Function(nameof(EntitiesController.Count)).Returns<int>();

Create the IEdmModel and call

var edmModel = odataBuilder.GetEdmModel();
var document = edmModel.ConvertToOpenApi();
Expected result

The OpenApiDocument gets created.

Actual result

System.InvalidOperationException: 'Collection was modified; enumeration operation may not execute.'
Following the StackTrace the reason is:
AppendBoundOperationOnNavigationSourcePath() has a foreach on IList, which calls AppendPath(newPath);, which results in a modification of the paths, if a dollar-count-similar path is found, hence resulting in the InvalidOperationException.

Additional detail

Creating a copy of the collection before iterating over it in ODataPathProvider.cs L950 would work in my use-case, but keeps the $count and Count() operations in the openapi specification. Don't know if that is a problem.

foreach (var subPath in value.ToList())
...

As a workaround - not using dollar-similar-paths in your OData operations removes the issue as well ;)

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs の 950 行目付近にある AppendBoundOperationOnNavigationSourcePath() から開始し、issue に記載されている Count() 操作で失敗を再現します。AppendPath が IList をどのように変更するかを追跡し、その後、$count と Count() のパスへの影響を確認しながら、ConvertToOpenApi がコレクション変更例外なしでドキュメントを作成することを検証します。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
csharp
領域
api
issue の種類
バグ
難易度
2/5
見積もり時間
1〜3時間
活発さ
停滞
明瞭さ
明確に書かれている
初心者へのやさしさ
68/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。