【问题标题】:Laravel 5.5 Validation change format of response when validation fails验证失败时,Laravel 5.5 Validation 更改响应格式
【发布时间】:2018-05-21 07:26:15
【问题描述】:

在 Laravel 5.4 中,我们创建了一个类,我们的所有验证请求都继承了该类,因为我们需要自定义响应。

class APIRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return false;
    }

    /**
     * Response on failure
     * 
     * @param array $errors
     * @return Response
     */
    public function response(array $errors) {
        $response = new ResponseObject();

        $response->code = ResponseObject::BAD_REQUEST;
        $response->status = ResponseObject::FAILED;
        foreach ($errors as $item) {
            array_push($response->messages, $item);
        }
        return Response::json($response);
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            //
        ];
    }
}

一个可以扩展它的示例请求如下所示

class ResultsGetTermsRequest extends APIRequest
{
    /**
     * 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 [
            'school_id' => 'required|integer',
            'student_id' => 'required|integer',
        ];
    }
}

然后我们对失败的示例响应将是

{
    "status": "FAILED",
    "code": "400",
    "messages": [
        [
            "The school id field is required."
        ],
        [
            "The student id field is required."
        ]
    ],
    "result": []
}

但是,这不再适用于 Laravel 5.5。我注意到他们用failedValidation 替换了响应方法。但是,当请求未经过验证时,这不会返回任何响应。如果我取消对 print_r 的注释,则会返回一些东西。似乎唯一从未执行的行是 return 语句。我错过了什么?

 public function failedValidation(Validator $validator) {

        $errors = (new ValidationException($validator))->errors();
        $response = new ResponseObject();

        $response->code = ResponseObject::BAD_REQUEST;
        $response->status = ResponseObject::FAILED;
        foreach ($errors as $item) {
            array_push($response->messages, $item);
        }
        //print_r($response);
        return Response::json($response);
    }

【问题讨论】:

  • 考虑到failedValidation 返回void 没有什么期望使用它的任何返回值...failedValidation 默认抛出异常
  • 我需要做什么才能发回响应?我怎么看,我唯一的其他选择是将验证逻辑放在我试图避免的控制器中!
  • 不,它根本不是唯一的选择......如果验证失败,它会抛出 ValidationException .. 该异常可以包含响应
  • 这是我必须在Handler.php 中放入App\Exceptions 命名空间的东西吗?我将寻找一种方法来做到这一点,但如果你有任何我可以使用的链接,请分享。

标签: php laravel validation laravel-5.5


【解决方案1】:

我猜根据 laravel upgrade 指南,我们应该返回 HttpResponseException

protected function failedValidation(Validator $validator)
{
    $errors = $validator->errors();
        $response = new ResponseObject();

        $response->code = ResponseObject::BAD_REQUEST;
        $response->status = ResponseObject::FAILED;
        foreach ($errors as $item) {
            array_push($response->messages, $item);
        }

    throw new HttpResponseException(response()->json($response));
}

【讨论】:

  • 最后发现解决办法是把最后一行改成throw new HttpResponseException(response()->json($response));
  • 感谢您编辑回复...让我将此标记为已接受的答案。我相信它会在未来对某人有所帮助。
【解决方案2】:

如果您想从 FormRequest 类中执行此操作,可能是这样的:

protected function buildResponse($validator)
{
    return response->json([
        'code' => ResponseObject::BAD_REQUEST,
        'status' => ResponseObject::FAILED,
        'messages' => $validator->errors()->all(),
    ]);
 }

protected function failedValidation(Validator $validator)
{
    throw (new ValidationException($validator, $this->buildResponse($validator));
}

这会将您正在构建的响应添加到验证异常中。当异常处理程序尝试渲染它时,它将检查是否设置了 response,如果设置了,它将使用您传递的响应,而不是尝试将 ValidationException 转换为响应本身。

如果您希望“所有”验证异常最终以这种格式呈现,我可能只是在异常处理程序级别执行此操作,因为异常处理程序已经能够将这些异常转换为 Json,因此您可以更改处理程序本身中的格式,基本上不必对默认的 FormRequest 进行任何调整。

【讨论】:

  • 我稍后会试试这个。请参阅提供解决方案的@vijaykumar 接受的答案。
  • 是的,结果相同,只是不需要在验证异常中进行响应
  • 谢谢,这正是我想要的
【解决方案3】:

如果您使用的是 laravel 5+,您可以通过覆盖 App/Exceptions/Handler.php 文件中的 invalid()invalidJson() 方法轻松实现这一目标

在我的例子中,我正在开发一个 API,并且 api 响应应该采用特定格式,所以我在 Handler.php 文件中添加了以下内容。

/**
     * Convert a validation exception into a JSON response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Illuminate\Validation\ValidationException  $exception
     * @return \Illuminate\Http\JsonResponse
     */
    protected function invalidJson($request, ValidationException $exception)
    {
        return response()->json([
            'code'    => $exception->status,
            'message' => $exception->getMessage(),
            'errors'  => $this->transformErrors($exception),

        ], $exception->status);
    }

// transform the error messages,
    private function transformErrors(ValidationException $exception)
    {
        $errors = [];

        foreach ($exception->errors() as $field => $message) {
           $errors[] = [
               'field' => $field,
               'message' => $message[0],
           ];
        }

        return $errors;
    }

信用:Origianal Answer

【讨论】:

    猜你喜欢
    • 2019-01-19
    • 1970-01-01
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    相关资源
    最近更新 更多