web-dev-qa-db-ja.com

[FromQuery]パラメーターでオーバーロード[HttpGet]メソッドを使用するようにASP.NETCORE 3.0でルーティングを構成するにはどうすればよいですか?

タイトルについて申し訳ありませんが、私はそれらが得意ではありません。質問の内容を説明するためのより良いタイトルを知っている場合はお知らせください。

したがって、2つのメソッドがあります。1つ目はすべてのリストアイテムを取得する方法で、2つ目はすべてのリストアイテムも取得する方法です。ただし、2つ目のメソッドにはクエリパラメーターがあり、これをフィルターに使用します。2つ目はメソッドは、最初のメソッドとは異なるオブジェクトも返します。同じルートに行く2つのHttpgetメソッドがあるので、メソッドの1つを呼び出すと、次のようになります。

Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException:要求が複数のエンドポイントに一致しました。一致:...。

2つのメソッドをマージしたり、オプションのパラメーターを使用したり、1つのメソッドのパスを変更したりせずに、これを解決するにはどうすればよいですか?可能なら??

サンプルコード:

// GET: api/Resources
[HttpGet]
public async Task<ActionResult<ICollection<Data>>> GetAll()
{
    return Ok(await Service.GetAll());
}

// GET: api/Resources
[HttpGet]
public async Task<ActionResult<Data2>> GetAll([FromQuery]int parameter)
{
    return Ok(await Service.GetAll2(parameter));
}

私が持っているconfigureメソッドの中に:

app.UseHttpsRedirection();

app.UseRouting();

app.UseAuthentication();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

編集:このような構成でアクションを利用するためにコメントによって提案されたように試みました...

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute("default", "{controller}/{action}/{id?}");
});

たとえば、最初のgetallメソッドにgetリクエストを実行すると、間違ったメソッドが呼び出されるため、機能しませんでした。api/ resources/getall getallは整数ではないため、代わりに以下のメソッドがトリガーされ、エラーが発生します。

// GET: api/Resources/5
[HttpGet("{id}")]
public async Task<ActionResult<Data>> GetById(int id)
{
    return Ok(await Service.GetById(id));
}

再現例>> https://drive.google.com/open?id=15EB1_kK-c_qyhRS0QvVlKnhuUbFjyN12


アクションが機能するようになり、コントローラーの属性ルーティングを変更する必要がありました...

[Route("api/[controller]/[action]")]
[ApiController]
public class ResourcesController : ControllerBase
{
    // GET: api/Resources/GetAll
    [HttpGet]
    public ActionResult<ICollection<string>> GetAll()
    {
        return Ok(new List<string>() { "foo", "bar" });
    }

    // GET: api/Resources/GetAll2?parameter="bar"
    [HttpGet]
    public ActionResult<string> GetAll2([FromQuery]string parameter)
    {
        return Ok(parameter);
    }

    // GET: api/Resources/GetById/5
    [HttpGet("{id}")]
    public ActionResult<int> GetById(int id)
    {
        return Ok(id);
    }
}

パスを変えないとこれを実現できないので、コントローラーでアクションを使用する代わりに、1つのメソッドのパスのみを変更し、メソッドを呼び出すときにパスにアクション名を追加する必要があります。

数週間後に私が遭遇した他の何かが機能する可能性があります(テストしませんでした) このビデオ に見られるようにルート制約の使用です。

2
Noob

参考までに、新しいWeb APIasp.netコア3プロジェクトを作成しました。

また、たとえば、デフォルトルートがStartup.cs。endpoints.MapDefaultControllerRoute();に登録されているとします。

追加する

_[Route("api/[controller]/[action]")]
[ApiController]
_

コントローラの起動時にスタートアップが上書きされるため、他のコントローラについて心配する必要はありません。

また、Idはオプションのパラメーターではこれを達成できません。あいまいになります。 GetAll()とGetAll(int parameter)はまったく同じであるため、パラメーターをオプションとして宣言しているためです。 これがエラーが発生する理由です。

_using Microsoft.AspNetCore.Mvc;

namespace WebApiTest.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class ResourceController : ControllerBase
    {

        [HttpGet]
        //api/Resource/GetAll
        public IActionResult GetAll()
        {
            return Content("I got nth");
        }

        //GET: //api/Resource/GetAll/2
        [HttpGet("{parameter}")]
        public IActionResult GetAll(int parameter)
        {
            return Ok($"Parameter {parameter}");
        }

    }
}
_

また、2番目のGetAll()で、HttpGetにパラメーターを追加したことにも注意してください。

これは、ルーティングエンジンを更新して、このルートにパラメータが含まれるようにするためです。ファイルの先頭にある汎用レベルでは、アクションまで登録しているためです。

より多くのパラメータについては、このようにsthを実行できます。 [HttpGet({parameter}/{resourceId})]

その場合、ルートは次のように機能しますapi/Resource/GetAll/2/4

0
panoskarajohn

2つのメソッドをマージしたり、オプションのパラメーターを使用したり、1つのメソッドのパスを変更したりせずに、これを解決するにはどうすればよいですか?可能なら??

これら2つのアクションをマージしたり、ルートでアクション名を指定したりせずに機能させたい場合は、Http[Verb] attributesを使用して、次のように2番目のアクションがルートデータからパラメーターを受け入れるようにすることができます。

// GET: api/Resources
[HttpGet]
public async Task<ActionResult<ICollection<Data>>> GetAll()
{
    return Ok(await Service.GetAll());
}


// GET: api/Resources/1
[HttpGet("{parameter:int}")]
public async Task<ActionResult<Data2>> GetAll([FromRoute]int parameter)
{
    return Ok(await Service.GetAll2(parameter));
}

その上、私の見解では、これら2つのアクションをマージし、オプションのパラメーターを使用する方がよいでしょう。要件を達成するためにこのアプローチを使用しない必要があるシナリオを知りたいのですが。

[HttpGet("{parameter:int?}")]
public async Task<IActionResult> GetAll([FromQuery]int parameter)
{
    if (parameter == 0)
    {
        return Ok(await Service.GetAll());
    }
    else
    {
        return Ok(await Service.GetAll2(parameter));
    }
}
1
Fei Han