我正在尝试为 API 编写 CRUD。但是,当验证失败时,我不想将用户重定向到主页,而是返回带有错误的基于
json
的响应。
我可以使用以下代码来做到这一点
public function store(Request $request)
{
try {
$validator = $this->getValidator($request);
if ($validator->fails()) {
return $this->errorResponse($validator->errors()->all());
}
$asset = Asset::create($request->all());
return $this->successResponse(
'Asset was successfully added!',
$this->transform($asset)
);
} catch (Exception $exception) {
return $this->errorResponse('Unexpected error occurred while trying to process your request!');
}
}
/**
* Gets a new validator instance with the defined rules.
*
* @param Illuminate\Http\Request $request
*
* @return Illuminate\Support\Facades\Validator
*/
protected function getValidator(Request $request)
{
$rules = [
'name' => 'required|string|min:1|max:255',
'category_id' => 'required',
'cost' => 'required|numeric|min:-9999999.999|max:9999999.999',
'purchased_at' => 'nullable|string|min:0|max:255',
'notes' => 'nullable|string|min:0|max:1000',
];
return Validator::make($request->all(), $rules);
}
现在,我喜欢将一些代码提取到
form-request
中以进一步清理我的控制器。我喜欢将我的代码更改为类似下面的代码。
public function store(AssetsFormRequest $request)
{
try {
if ($request->fails()) {
return $this->errorResponse($request->errors()->all());
}
$asset = Asset::create($request->all());
return $this->successResponse(
'Asset was successfully added!',
$this->transform($asset)
);
} catch (Exception $exception) {
return $this->errorResponse('Unexpected error occurred while trying to process your request!');
}
}
您可能会说
$request->fails()
和 $request->errors()->all()
不起作用。如何检查请求是否失败,然后如何从表单请求中获取错误?
供您参考,这是我的
AssetsFormRequest
课程的样子
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class AssetsFormRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|string|min:1|max:255',
'category_id' => 'required',
'cost' => 'required|numeric|min:-9999999.999|max:9999999.999',
'purchased_at' => 'nullable|string|min:0|max:255',
'notes' => 'nullable|string|min:0|max:1000',
];
}
}
在您的 AssetFormRequest 类中,您可以 覆盖 failedValidation 方法到以下 -
public $validator = null;
protected function failedValidation(\Illuminate\Contracts\Validation\Validator $validator)
{
$this->validator = $validator;
}
然后你的控制器方法,用你的 $validator 对象做任何你想做的事情。可能是下面这样的-
if (isset($request->validator) && $request->validator->fails()) {
return response()->json($request->validator->messages(), 400);
}
您也可以查看this链接以获取更多详细信息。 希望有帮助:)
将此功能添加到您的请求中:
public function withValidator($validator)
{
if ($validator->fails()) {
Session::flash('error', 'Flash error!');
} else {
}
}
已经过去两年了,但这也许会对某人有所帮助。
您可以通过添加(在 Laravel 6.0.4 中测试)来重写 AssetFormRequest 中的 getValidatorInstance() 方法:
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
use Illuminate\Contracts\Validation\Validator;
/**
* Get the validator instance for the request.
*
* @return Validator
* @throws BindingResolutionException
*/
public function getValidatorInstance()
{
if ($this->validator) {
return $this->validator;
}
$factory = $this->container->make(ValidationFactory::class);
if (method_exists($this, 'validator')) {
$validator = $this->container->call([$this, 'validator'], compact('factory'));
} else {
$validator = $this->createDefaultValidator($factory);
}
if (method_exists($this, 'withValidator')) {
$this->withValidator($validator);
}
$this->setValidator($validator);
return $this->validator;
}
之后,您的控制器中就可以使用验证器了:
public function store(AssetsFormRequest $request)
{
$validator = $request->getValidatorInstance();
try {
if ($validator->fails()) {
return $this->errorResponse($validator->errors());
}
$asset = Asset::create($validator->validated());
return $this->successResponse(
'Asset was successfully added!',
$this->transform($asset)
);
} catch (Exception $exception) {
return $this->errorResponse('Unexpected error occurred while trying to process your request!');
}
}
我执行了以下操作来解决此问题:A
FormRequest
可以访问 Validator
实例,因此您可以通过此检查 Validator
实例的 MessageBag
实例上是否存在任何失败的规则或错误消息,如下所示:
解决方案1:
sizeof($request?->validator?->failedRules) === 0
在这里检查failedRules
array
是否没有任何或没有失败的规则。
解决方案2.
sizeof($request?->validator?->messages?->messages) === 0
在这里检查 MessageBag
实例的 message
array
属性是否有验证失败错误消息。