3

私は MVC Web Api を初めて使用しますが、ServiceStack フレームワークを使用した経験があります。Web API の例のいくつかは、アクション メソッドが多く、パラメーターが少ない RPC によく似ています。実際、ほとんどの例では、リクエスト パラメータを ID に制限しているようです。リクエストはすべてのレポート基準で非常に複雑になるため、リクエスト/レスポンスを使用していくつかのレポート サービスを作成したいと考えています。

これが私の単純化されたリクエスト/レスポンスタイプです:

public class PendingRequest
{
    public string Id { get; set; }
    public int AccountId { get; set; }
    public DateTime? FromDate { get; set; }
    public DateTime? ToDate { get; set; }
}

public class PendingResponse
{
    public string Id { get; set; }
    public IEnumerable<Pending> Data { get; set; }
}

そして、私のアウトラインレポートコントローラー:

public class ReportsController : ApiController
{
    public async Task<PendingResponse> GetPending(PendingRequest request)
    {
        return new PendingResponse
        {
            Id = request.Id,
            // Data = await Repo.GetPending()
        };
    }

    public async Task<ShippedResponse> GetShipped(ShippedRequest request)
    {
        return new ShippedResponse
        {
            Id = request.Id,
            // Data = await Repo.GetShipped()
        };
    }

    public async Task<ProductsResponse> GetProducts(ProductsRequest request)
    {
        return new ProductsResponse
        {
            Id = request.Id,
            // Data = await Repo.GetProducts()
        };
    }
}

そして、セルフホスティングアプリのルーティングと設定:

class Program
{
    static void Main()
    {
        var config = new HttpSelfHostConfiguration("http://localhost:8080");

        config.Routes.MapHttpRoute(
            name: "Reports",
            routeTemplate: "api/reports/{action}",
            defaults: new
                {
                    controller = "Reports"
                });

        using (var server = new HttpSelfHostServer(config))
        {
            server.OpenAsync().Wait();
            Console.WriteLine("Press Enter to quit.");
            Console.ReadLine();
        }
    }
}

したがって、このルーティングでは、アクションをレポートの名前にするつもりです。ここにはリクエストパラメータを含めていないことに注意してください。私がすべきかどうかわからない。

問題は実際にはクライアント側にあります。HttpClient では、GetAsync メソッドで JSON 要求オブジェクトを含めることができません。拡張メソッド PostAsJsonAsync が表示されますが、これは POST ではないはずですか? GetAsJsonAsync などがなければ、GET でリクエストを含める方法がわかりませんか?

正直なところ、私は ServiceStack の方が好きですが、非同期サポートはまだないようです。I/O 集中型の高性能サービスを開発する必要があり、ブロッキングをできるだけ減らしたいと考えています。

アップデート:

リクエスト本文を使用するのではなく、クエリ文字列の一部としてモデルのパラメーターを含めると、Web Api がモデル バインディングを実行するようです。これを機能させるには、Get メソッドでモデル タイプの前に [FromUri] 属性を付ける必要があります。これにより、モデル バインダーに、要求クエリ文字列からモデルを構築する必要があることが通知されます。面倒ですが、機能します。

[ActionName("Pending")]
public async Task<PendingResponse> GetPending([FromUri] PendingRequest request)
{
    return new PendingResponse
    {
        Id = request.Id,
        // query = ...build from request params
        // Data = await Repo.GetPending(query)
    };
}

そして今、クライアント側で次のことを実行します。

var result = await _httpClient.GetAsync("api/reports/pending?Id=123&AccountId=456");
result.EnsureSuccessStatusCode();
var response = await result.Content.ReadAsAsync<PendingResponse>();

サービスを呼び出すと、GetPending メソッドが呼び出され、指定されたクエリ文字列パラメーターから具体化された PendingRequest オブジェクトのコピーが呼び出されます。

4

2 に答える 2

3

ここでの根本的な問題は、許可されていない HTTP GET にリクエスト本文を提供しようとしていることです。まあ、リクエスト本文でGETをフォーマットして送信することはできますが、それは仕様に従っていません。厳密に言えば、HTTP 仕様では GET リクエストがボディを持つことを禁止していませんが、GET リクエストの応答はリクエスト ボディに基づいて変更してはなりません。つまり、基本的に GET リクエスト ボディで検索条件を使用することはできません。URI パスとクエリ文字列を使用して検索基準を指定できます。それらを複合型パラメーターにバインドする場合は、次の[FromUri]ように使用する必要がありますpublic async Task<PendingResponse> GetPending([FromUri]PendingRequest request)

于 2013-08-29T13:37:58.720 に答える
0

少し推測ですが、JSON 要求オブジェクトを URL エンコードして、GET URI のクエリ文字列セグメントに入れるだけではどうでしょうか?

また、複雑なタイプであるため、アクションのリクエスト メソッド パラメータに [FromUri] 属性が必要になる場合があります。何かを見逃しているかもしれませんが、パラメーター バインディングに関するこの記事では、GET が複合型の特殊なケースであることについては何も言及していません。

于 2013-08-29T07:40:01.113 に答える