1

ODataController クラスを使用し、Entity Framework で同時実行チェックをサポートすることで、OData v4 プロトコルで WebAPI 2 サービスを作成しました。クライアント側のコードは、Odata クライアント T4 テンプレートを使用して生成されます。このコードは、エンティティの追跡を処理し、Odata URL の LINQ クエリを解析する DataServiceContext から派生したプロキシ クラスとコンテナー クラスを生成します。追跡対象のエンティティ (同時実行性がチェックされるプロパティを含む) が更新されると、SaveChangesAsync メソッドを呼び出すコンテナー クラスが HTTP PATCH を生成します。そのエンティティの最後のクエリから受け取った値を持つ If-Match ヘッダーを含むリクエストで、正常に動作します。

Fiddler によってキャッチされるリクエストの例:

パッチ /Users(2) HTTP/1.1

キャッシュ

If-Match: W/"J1Z1a2FzaWU3Bhc2IjJw=="

ただし、コンテナがエンティティのクエリを作成する場合、正しい HTTP GET リクエストを生成します

(リクエストの例:

GET /Animals(8) HTTP/1.1)

ただし、If-None-Match ヘッダーがない場合、最後のクエリであっても、サービスは応答で etag 値を送信します

(応答の例:

@odata.etag=W/"J0MxRjIn")

コンテナー コンテキスト構成の requestpipeline プロパティを設定するか、他の方法で If-None-Match ヘッダーを追加することは可能ですか? 備考を追加する - サービスが GET 要求の If-None-Match ヘッダーで etag 値を取得する場合、etag 値が一致する場合 (エンティティが変更されないことを意味する)、ステータス コード 304 NotModified を返す必要があります。それ以外の場合、サービスは応答本文でエンティティ プロパティを送信します。 .

アップデート:

SendingRequest2 を処理して If-None-Match を追加しようとしたところ、If-None-Match ヘッダーを手動で追加できるようになりましたが、その場合、サービスがリクエストを受信して​​そこから etag を読み取るときに、エンティティが変更されていない場合 (etag が一致する場合) 、答えは statuscode 304 - NotModified であり、コンテナー (派生 DataServiceContext クラスのインスタンス) はその応答を処理できません。これは、本文メッセージにエンティティーが含まれていると予想されるため、例外が生成されるためです。例外を処理し、それを使用してエンティティが変更されていないことを確認できますが、これはプログラミングを行うための最適化された方法ではありません。リクエストとレスポンスのパイプライン イベントに入る方法が必要です。リクエスト パイプラインでは、単一のクエリ リクエストに etag を追加し、応答パイプラインでは、受信したステータス コード 304 - NotModified を処理します。

context.Configuration.RequestPipeline のリストは次のとおりです。

OnEntityReferenceLink(アクション アクション);

OnEntryEnding(アクション アクション);

OnEntryStarting(アクション アクション);

OnMessageWriterSettingsCreated(アクション引数);

OnNavigationLinkEnding(アクション アクション);

OnNavigationLinkStarting(アクション アクション);

context.Configuration.ResponsePipeline のリストは次のとおりです。

OnEntityMaterialized(アクション アクション);

OnEntryEnded(アクション アクション);

OnEntryStarted(アクション アクション);

OnFeedEnded(アクション アクション);

OnFeedStarted(アクション アクション);

OnMessageReaderSettingsCreated(Action messageReaderSettingsAction);

OnNavigationLinkEnded(アクション アクション);

OnNavigationLinkStarted(アクション アクション);

4

1 に答える 1

2

リクエストを送信する前に次のコードを追加すると、機能するはずです。

context.SendingRequest2+= (sender, eventArgs) =>
{
    eventArgs.RequestMessage.SetHeader("If-None-Match", "xxxxxxx");
};

の派生クラスのcontextインスタンスの名前です。DataServiceContext

于 2014-10-09T08:51:19.430 に答える