use*_*602 6 laravel laravel-5 laravel-validation laravel-5.5
我没有得到我期望的答复。
这是“位置” Web服务请求的控制器代码:
<?php
namespace App\Http\Controllers;
use App\Location;
use Illuminate\Http\Request;
class LocationController extends Controller
{
/**
* Action method to add a location with the supplied Data
*
* @param \Illuminate\Http\Request $p_oRequest Request
*
* @return JSON
*/
public function add(Request $p_oRequest)
{
try {
$p_oRequest->validate(
array(
'name' => 'required|alpha_num',
'user_id' => 'required|integer',
),
array(
'name.required' => 'Name is required',
'name.string' => 'Name must be alphanumeric',
'user_id.required' => 'Curator User Id is required',
'user_id.required' => 'Curator User Id must be an integer',
)
);
} catch (\Exception $ex) {
$arrResponse = array(
'result' => 0,
'reason' => $ex->getMessage(),
'data' => array(),
'statusCode' => 404
);
} finally {
return response()->json($arrResponse);
}
}
}
Run Code Online (Sandbox Code Playgroud)
该请求是http://mydomain/index.php/api/v1/location/add?name = @!^
我期望的响应原因是:{“结果”:0,“原因”:“名称必须是字母数字”,“数据”:[],“ statusCode”:404}
我得到的实际响应是:{“ result”:0,“ reason”:“给定的数据无效。”,“ data”:[],“ statusCode”:404}
请帮忙。这使我烦恼。
我终于发现了为什么这行不通。这不是实现代码或Laravel中的错误问题,而是以下两者之一:(i)。编写出色的PHP代码来处理不言而喻的结果,显然我没有这么做;(ii)。Laravel中关于如何实际使用验证错误响应的文档不足。随便你吧。
Laravel的验证会抛出Illuminate \ Validation \ ValidationError。信不信由你,这实际上将错误消息默认为“给定数据无效。”,因此,当您捕获\ Exception并检索其$ e-> getMessage()时,此默认错误消息就是您(正确)的错误消息得到。
您需要做的是捕获\ Illuminate \ Validation \ ValidationError-我本来应该做的,du!-然后使用其方法来帮助您从中提取错误消息。
这是我想出的解决方案:
<?php
namespace App\Http\Controllers;
use App\Location;
use Illuminate\Http\Request;
class LocationController extends Controller
{
/**
* Action method to add a location with the supplied Data
*
* @param \Illuminate\Http\Request $p_oRequest Request
*
* @return JSON
*/
public function add(Request $p_oRequest)
{
try {
$arrValid = array(
'name' => 'required|alpha_num',
'user_id' => 'required|integer',
);
$p_oRequest->validate(
$arrValid,
array(
'name.required' => 'Name is missing',
'name.alpha_num' => 'Name must be alphanumeric',
'user_id.required' => 'User Id is missing',
'user_id.integer' => 'User Id must be an integer',
)
);
} catch (\Illuminate\Validate\ValidationException $e ) {
/**
* Validation failed
* Tell the end-user why
*/
$arrError = $e->errors(); // Useful method - thank you Laravel
/**
* Compile a string of error-messages
*/
foreach ($arrValid as $key=>$value ) {
$arrImplode[] = implode( ', ', $arrError[$key] );
}
$message = implode(', ', $arrImplode);
/**
* Populate the respose array for the JSON
*/
$arrResponse = array(
'result' => 0,
'reason' => $message,
'data' => array(),
'statusCode' => $e->status,
);
} catch (\Exception $ex) {
$arrResponse = array(
'result' => 0,
'reason' => $ex->getMessage(),
'data' => array(),
'statusCode' => 404
);
} finally {
return response()->json($arrResponse);
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,确实,Laravel提供了正确的响应,并且做到了锡盒侧面所说的,但是我没有正确地应用它。无论如何,为了对我和Laravel-sea的其他丢失PHP的航海者未来有所帮助,我提供了解决方案。
另外,还要感谢Marcin指出我的错误代码,即使我已经实现了上述解决方案,也会造成问题。
问题可能是Laravel的默认Exception处理程序没有准备好将详细的验证信息中继回用户。相反,它向用户隐藏了异常详细信息,这通常是正确的做法,因为它可能对除验证之外的其他异常构成安全风险。
换一种说法; 如果Exception Handler的render功能(在中实现/app/Exceptions/Handler.php)捕获到您的验证错误,则它们将被解释为一般应用程序Exception,并且传递给用户的一般错误消息将始终显示“给定数据无效”。
确保该render方法忽略的实例\Illuminate\Validation\ValidationException,并且应该获得期望的响应:
public function render($request, Exception $exception) {
if (! $exception instanceof \Illuminate\Validation\ValidationException)) {
// ... render code for other Exceptions here
}
}
Run Code Online (Sandbox Code Playgroud)
使异常处理程序通过响应中继ValidationException详细信息的另一种方法是在render方法中执行以下操作:
if ($exception instanceof ValidationException && $request->expectsJson()) {
return response()->json(['message' => 'The given data was invalid.', 'errors' => $exception->validator->getMessageBag()], 422);
}
Run Code Online (Sandbox Code Playgroud)
Laravel基本上在这里使用异常。通常,Exception表示代码中的(运行时)问题,但是Laravel使用它们作为一种机制来促进请求验证并向用户提供反馈。这就是为什么在这种情况下,让您的异常处理程序处理异常是不正确的-它不是应用程序异常,而是给用户的信息。
OP提供的答案中的代码行之有效,因为他自己捕获了ValidationException,从而阻止了它被应用程序的Exception Handler捕获。我认为在任何情况下都不会出现这种情况,因为这是各种关注的明确组合,并且会导致代码太长且难以阅读。像我上面显示的那样,简单地忽略ValidationExceptions或在Exception Handler中对它们进行不同的处理,就可以解决问题。
我刚刚看到这个,但你需要做的就是在 try/catch之前移动验证调用
$p_oRequest->validate(
[
'name' => 'required|alpha_num',
'user_id' => 'required|integer',
],
[
'name.required' => 'Name is required',
'name.string' => 'Name must be alphanumeric',
'user_id.required' => 'Curator User Id is required',
'user_id.required' => 'Curator User Id must be an integer',
]
);
try {
...
} catch(\Exception $e) {
return back()->withErrors($e->getMessage())->withInput();
}
Run Code Online (Sandbox Code Playgroud)
因为 Laravel 会自动捕获验证异常并返回旧输入和一系列错误,您可以像这样输出
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11632 次 |
| 最近记录: |