如何使用自定义规则抛出404 in-Laravel表单请求
通常,如果验证失败,Laravel的表单请求会返回一个通用的如何使用自定义规则抛出404 in-Laravel表单请求,laravel,http-status-code-404,rules,Laravel,Http Status Code 404,Rules,通常,如果验证失败,Laravel的表单请求会返回一个通用的400代码,如下所示: { "message": "The given data is invalid", "errors": { "person_id": [ "A person with ID c6b853ec-b53e-4c35-b633-3b1c2f27869c does not exist"
400
代码,如下所示:
{
"message": "The given data is invalid",
"errors": {
"person_id": [
"A person with ID c6b853ec-b53e-4c35-b633-3b1c2f27869c does not exist"
]
}
}
如果请求未通过我的自定义规则,我想返回404
我的自定义规则检查数据库中是否存在记录:
class ValidatePersonExists implements Rule
{
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
public function passes($attribute, $value)
{
return Person::where('id', $value)->exists();
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return "A person with ID :input does not exist";
}
}
如果我在exists()
检查失败时抛出ModelNotFoundException
,我在哪里可以捕捉到它以友好的404响应
这是我使用规则的表单请求:
public function rules()
{
return [
'person_id' => ['bail', 'required', 'uuid', new ValidatePersonExists],
];
}
您可以修改app/Exceptions/Handler.php,下面是我如何使用它的
use Illuminate\Database\Eloquent\ModelNotFoundException;
public function render($request, Exception $e)
{
$status = method_exists($e, 'getStatusCode') ? $e->getStatusCode() : 500;
//here im using translation, you can set your own message
$response = [
'errors' => trans("response.$status.response"),
'message' => trans("response.$status.message")
];
if (config('app.debug')) {
$response['exception'] = get_class($e);
$response['message'] = $e->getMessage();
$response['trace'] = $e->getTrace();
}
//ModelNotFoundException statusCode is 0 so i need to pass it manually
if($e instanceof ModelNotFoundException){
$response['errors'] = new \Illuminate\Support\ViewErrorBag;
$response['response'] = 404; // im using translation here
return response()->view("errors.index", $response, 404);
}
return parent::render($request, $e);
}
在我的刀片中,有一条简单的翻译信息:
<p>{{trans("response.{$response}.response")}}</p>
<p>{{trans("response.{$response}.message")}}</p>
{{trans(“response.{$response}.response”)}
{{trans(“response.{$response}.message”)}
您可以修改app/Exceptions/Handler.php,下面是我如何使用它的
use Illuminate\Database\Eloquent\ModelNotFoundException;
public function render($request, Exception $e)
{
$status = method_exists($e, 'getStatusCode') ? $e->getStatusCode() : 500;
//here im using translation, you can set your own message
$response = [
'errors' => trans("response.$status.response"),
'message' => trans("response.$status.message")
];
if (config('app.debug')) {
$response['exception'] = get_class($e);
$response['message'] = $e->getMessage();
$response['trace'] = $e->getTrace();
}
//ModelNotFoundException statusCode is 0 so i need to pass it manually
if($e instanceof ModelNotFoundException){
$response['errors'] = new \Illuminate\Support\ViewErrorBag;
$response['response'] = 404; // im using translation here
return response()->view("errors.index", $response, 404);
}
return parent::render($request, $e);
}
在我的刀片中,有一条简单的翻译信息:
<p>{{trans("response.{$response}.response")}}</p>
<p>{{trans("response.{$response}.message")}}</p>
{{trans(“response.{$response}.response”)}
{{trans(“response.{$response}.message”)}
我找到了一个解决方案,但我不是100%满意
基本上,我创建了一个类(ApiRequest.php)来扩展Illumb的FormRequest类,在这个ApiRequest类中,我截取IlluminateValidationException
并对失败的验证执行一些逻辑,检查请求是否在我的exists()
规则中失败。如果是,我将状态代码更改为404:
这是我的班级:
abstract class ApiRequest extends IlluminateFormRequest
{
/**
* Handle a failed validation attempt.
*
* @param \Illuminate\Contracts\Validation\Validator $validator
* @return void
*
* @throws \GetCandy\Api\Exceptions\ValidationException
*/
protected function failedValidation(Validator $validator)
{
$failedRules = $validator->failed();
$statusCode = $this->getStatusCode($failedRules);
$response = new JsonResponse([
'message' => 'The given data is invalid',
'errors' => $validator->errors(),
], $statusCode);
throw new IlluminateValidationException($validator, $response);
}
private function getStatusCode($failedRules)
{
$statusCode = 400;
foreach ($failedRules as $rule) {
if (Arr::has($rule, "App\Http\Requests\Rules\ValidatePersonExists")) {
$statusCode = 404;
}
}
return $statusCode;
}
}
希望这对某人有所帮助,如果有人有更好的解决方案,请随时发布答案。我找到了一个解决方案,但我不是100%满意 基本上,我创建了一个类(ApiRequest.php)来扩展Illumb的FormRequest类,在这个ApiRequest类中,我截取
IlluminateValidationException
并对失败的验证执行一些逻辑,检查请求是否在我的exists()
规则中失败。如果是,我将状态代码更改为404:
这是我的班级:
abstract class ApiRequest extends IlluminateFormRequest
{
/**
* Handle a failed validation attempt.
*
* @param \Illuminate\Contracts\Validation\Validator $validator
* @return void
*
* @throws \GetCandy\Api\Exceptions\ValidationException
*/
protected function failedValidation(Validator $validator)
{
$failedRules = $validator->failed();
$statusCode = $this->getStatusCode($failedRules);
$response = new JsonResponse([
'message' => 'The given data is invalid',
'errors' => $validator->errors(),
], $statusCode);
throw new IlluminateValidationException($validator, $response);
}
private function getStatusCode($failedRules)
{
$statusCode = 400;
foreach ($failedRules as $rule) {
if (Arr::has($rule, "App\Http\Requests\Rules\ValidatePersonExists")) {
$statusCode = 404;
}
}
return $statusCode;
}
}
希望这对其他人有所帮助,如果有人有更好的解决方案,请随时发布答案。您在控制器中如何处理它?控制器没有收到它。Laravel的表单请求执行验证,然后返回。然后尝试仅使用验证器验证控制器中的数据,如果验证器失败,您可以发送404状态码。您如何在控制器中处理它?它不会到达控制器。Laravel的表单请求执行验证,然后尝试仅使用验证程序验证控制器中的数据,如果验证程序失败,则可以使用Illumb\Http\Exceptions\HttpResponseException发送404 status code.im进行api错误验证,并使用Illumb\validation\ValidationException发送failedValidationim中的formDataIllumb\Http\Exceptions\HttpResponseException用于api错误验证,Illumb\validation\ValidationException用于failedValidation中的formData