web-dev-qa-db-ja.com

ASP.NET Coreの必須クエリ文字列パラメーター

VS2015(sdk 1.0.0-preview2-003131)でASP.NET Core 1.1を使用すると、次のコントローラーがあります。

public class QueryParameters
{
    public int A { get; set; }
    public int B { get; set; }
}

[Route("api/[controller]")]
public class ValuesController : Controller
{
    // GET api/values
    [HttpGet]
    public IEnumerable<string> Get([FromQuery]QueryParameters parameters)
    {
        return new [] { parameters.A.ToString(), parameters.B.ToString() };
    }        
}

ご覧のとおり、2つのクエリパラメーターがあります。私が望むのは、それらの1つ(例:A)を必要とすることです。つまり、(可能であれば)属性を使用して、この属性が必須であることを伝えたいと思います。次に、ASP.NETにコントローラーを呼び出す前にこの検証を実行してもらいたいと思います。

Newtonsoft RequiredAttribute を使用してPUT/POSTコンテンツの必須プロパティを検証するために既に使用しているものと同じ属性を使用したいと思いますが、urlはJSON文字列ではないため、明らかに使用されていない。

ASP.NET Coreに必要なクエリパラメーターを自動的にチェックさせる提案はありますか?

Nullを許可するクエリパラメーターを使用して自分でチェックをコーディングできることは知っていますが、ASP.NETにコントローラーを呼び出す前に検証を行わせて、コントローラーを整頓するという目的に打ち勝ちます。

8
mabead

フレームワークのモデルバインディング機能の使用を検討できます。

ここのドキュメントによると: 属性を使用したモデルバインディング動作のカスタマイズ

MVCには、デフォルトのモデルバインディング動作を別のソースに向けるために使用できるいくつかの属性が含まれています。たとえば、プロパティにバインドが必要かどうか、またはバインドがまったく発生しないようにするかどうかを指定するには、[BindRequired]または[BindNever]属性。

そのため、モデルプロパティにBindRequiredAttributeを追加することをお勧めします。

public class QueryParameters
{
    [BindRequired]
    public int A { get; set; }
    public int B { get; set; }
}

そこから、フレームワークはモデルの状態のバインディングと更新を処理できるようになり、アクションでモデルの状態を確認できます。

[Route("api/[controller]")]
public class ValuesController : Controller
{
    // GET api/values
    [HttpGet]
    public IActionResult Get([FromQuery]QueryParameters parameters)
    {    
        if (ModelState.IsValid)
        {
            return Ok(new [] { parameters.A.ToString(), parameters.B.ToString() });
        }
        return BadRequest();
    }        
}

他のオプションは、必要なクエリ文字列が存在しない場合にアクションをフォールトするカスタムモデルバインダーを作成することです。

参照: カスタムモデルバインディング

19
Nkosi

フレームワークに任せてください。 ASP.NET Coreで同じことを実現する方法がいくつかあるように見えるので、ここに1つのソリューションがあります。しかし、これは私のために働くものであり、非常に簡単です。それはすでに与えられた答えのいくつかの組み合わせのようです。

public class QueryParameters
{
    [Required]
    public int A { get; set; }

    public int B { get; set; }
}

[Route("api/[controller]")]
public class ValuesController : Controller
{
    // GET api/values
    // [HttpGet] isn't needed as it is the default method, but ok to leave in
    // QueryParameters is injected here, the framework takes what is in your query string and does its best to match any parameters the action is looking for. In the case of QueryParameters, you have A and B properties, so those get matched up with the a and b query string parameters
    public IEnumerable<string> Get(QueryParameters parameters)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(); // or whatever you want to do
        }

        return new [] { parameters.a.ToString(), parameters.b.ToString() };
    }        
}
2
Jeff Magill

属性ルーティングを使用し、関数のHttpGet属性に必要な各パラメーターをリストします。

[Route("api/[controller]")]
public class ValuesController : Controller
{
    [HttpGet("{A}")]
    public IEnumerable<string> Get(int A, int B)
    {
       return new [] { A.ToString(), B.ToString() };
    }
}

これには、たとえば/ 5が必要であり、/ 5?B = 6クエリURLパラメータが許可されます。

1
Esa Komulainen