我正在努力实现symfony validation asset该要求。
我正在form-data从邮递员传递到控制器中的路线。
#[Route(path: '/test', name: 'test', methods: 'GET')]
public function login(LoginRequest $loginRequest): Response
Run Code Online (Sandbox Code Playgroud)
我创建了一个loginRequestDTO,如下所示:
class LoginRequest
{
public function __construct(
/**
* @Assert\NotBlank
*/
public string $username,
/**
* @Assert\NotBlank
*/
public string $password
) {
}
}
Run Code Online (Sandbox Code Playgroud)
但我收到以下错误。
Cannot autowire service "App\Dto\LoginRequest": argument "$username" of method "__construct()" is type-hinted "string", you should configure its value explicitly.
Run Code Online (Sandbox Code Playgroud)
有人可以帮助我如何使用 DTO 来验证参数请求吗?
小智 6
您可以编写自己的参数解析器,它将在控制器操作中注入任何实现的对象DtoResolvedInterface
// src/ArgumentResolver/DtoValueResolver.php
class DtoValueResolver implements ArgumentValueResolverInterface
{
public function __construct(
private readonly DenormalizerInterface $denormalizer,
private readonly ValidatorInterface $validator
) {
}
public function supports(Request $request, ArgumentMetadata $argument): bool
{
return $argument->getType() && str_starts_with($argument->getType(), DtoResolvedInterface::class);
}
public function resolve(Request $request, ArgumentMetadata $argument): iterable
{
try {
$dtoValue = $this->denormalizer->denormalize($request->toArray(), $argument->getType());
} catch (NotNormalizableValueException $e) {
// wrong types
throw new BadRequestHttpException();
}
$violations = $this->validator->validate($dtoValue);
if ($violations->count() > 0) {
// dto is not valid
throw new BadRequestHttpException((string) $violations);
}
yield $dtoValue;
}
}
Run Code Online (Sandbox Code Playgroud)
声明任何空接口只是为了区分 DTO 类。
interface DtoResolvedInterface
{
}
Run Code Online (Sandbox Code Playgroud)
并在您的 LoginRequest 中实现此接口
class LoginRequest implements DtoResolvedInterface
{
public function __construct(
/**
* @Assert\NotBlank
*/
public string $username,
/**
* @Assert\NotBlank
*/
public string $password
) {
}
}
Run Code Online (Sandbox Code Playgroud)
您需要在方法中使用Serializer 组件并反序列化 DTO 以使用数据创建对象。创建带有 header 的请求Content-Type: application/json并以 json 格式发送数据,而不是form-data
您的 DTO 应该这样声明:
use Symfony\Component\Validator\Constraints as Assert;
class LoginRequest
{
/**
* @Assert\NotBlank()
*/
public string $username;
/**
* @Assert\NotBlank()
*/
public string $password;
}
Run Code Online (Sandbox Code Playgroud)
控制器方法:
use Symfony\Component\Serializer\SerializerInterface;
#[Route(path: '/test', name: 'test', methods: 'GET')]
public function login(Request $request, SerializerInterface $serializer, ValidatorInterface $validator): Response
{
$dto = $serializer->deserialize($request->getContent(), LoginRequest::class, 'json');
$errors = $validator->validate($dto);
if (count($errors) > 0) {
throw new BadRequestHttpException((string) $errors);
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7363 次 |
| 最近记录: |