core 3.1で
ActionFilterAttributeを使ってみたのですが
ずいぶん変わっているようですね?
ValidateIdAttribute.cs
using
System.Linq
;
using
Microsoft.AspNetCore.Mvc
;
using
Microsoft.AspNetCore.Mvc.Filters
;
using
Microsoft.AspNetCore.Mvc.ModelBinding
;
using
Microsoft.Extensions.Logging
;
namespace
FiltersSample.Filters
public
class
ValidateIdAttribute
:
ActionFilterAttribute
// パラメータのnullチェックをするかどうか
public
string
ParameterName
{
get
;
set
;
}
private
readonly
ILogger
<
ValidateIdAttribute
>
_logger
;
public
ValidateIdAttribute
()
_logger
=
new
LoggerFactory
().
CreateLogger
<
ValidateIdAttribute
>();
ParameterName
=
"id"
;
public
override
void
OnActionExecuting
(
ActionExecutingContext
actionContext
)
if
(!
actionContext
.
ActionArguments
.
All
(
x
=>
x
.
Key
!=
ParameterName
||
checkValue
(
x
.
Value
as
string
??
string
.
Empty
)))
// 数字じゃない
string
message
=
$"バリデート:
{
ParameterName
}
に数字以外が含まれます。"
;
actionContext
.
ModelState
[
ParameterName
].
Errors
.
Add
(
message
);
actionContext
.
ModelState
[
ParameterName
].
ValidationState
=
ModelValidationState
.
Invalid
;
_logger
.
LogError
(
message
);
actionContext
.
Result
=
new
BadRequestObjectResult
(
actionContext
.
ModelState
);
//actionContext.Result = new BadRequestResult();// こっちだと既定のbodyが返る
else
if
(!
actionContext
.
ModelState
.
IsValid
)
// Data Annotationsでひっかかった
string
message
=
string
.
Join
(
"; "
,
actionContext
.
ModelState
.
Select
(
pair
=>
$"
{
pair
.
Key
}
=
{
pair
.
Value
.
RawValue
.
ToString
()}
"
));
_logger
.
LogError
(
$"バリデート:
{
message
}
"
);
actionContext
.
Result
=
new
BadRequestObjectResult
(
actionContext
.
ModelState
);
//actionContext.Result = new BadRequestResult();// こっちだと既定のbodyが返る
// その他チェックすべきものがあれば実装
base
.
OnActionExecuting
(
actionContext
);
private
bool
checkValue
(
string
id
)
return
id
.
Length
==
12
&&
id
.
All
(
char
.
IsDigit
);
呼び出すのは
IdController.cs
using
FiltersSample.Filters
;
using
Microsoft.AspNetCore.Mvc
;
using
Microsoft.Extensions.Logging
;
using
System.Collections.Generic
;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace
FiltersSample.Controllers
[
Route
(
"api/[controller]"
)]
[
ApiController
]
public
class
IdController
:
ControllerBase
// GET: api/<IdController>
[
HttpGet
]
[
ValidateId
(
ParameterName
=
"id"
)]
public
IEnumerable
<
string
>
Get
(
string
id
)
return
new
string
[]
{
"id"
,
id
};
な感じでいいいみたいです
https://localhost:xxxx/api/Id?id=12345678
な感じでリクエストしてみてください
https://dev.azure.com/lowguy/_git/sample?path=%2F3.1sample