我没有得到我期望的回应。
这是位置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);
}
}
}
请求是http://mydomain/index.php/api/v1/location/add?name=@!^
我期望的回应原因是:{“结果”:0,“原因”:“名称必须是字母数字”,“数据”:[],“statusCode”:404}
我得到的实际响应是:{“结果”:0,“原因”:“给定数据无效。”,“数据”:[],“statusCode”:404}
请帮忙。这让我烦恼。
答案 0 :(得分:6)
我终于发现了为什么这不起作用。这不是执行代码或Laravel中的错误问题,而是其中之一:(i)。编写好的PHP代码来处理不言自明的结果,这显然是我没有做到的; (ⅱ)。 Laravel中有关如何实际使用验证错误响应的文档不足。随便挑选。
Laravel的验证会抛出Illuminate \ Validation \ ValidationError。信不信由你,这实际上默认错误信息为“给定的数据无效。”所以当你捕获一个\ Exception并检索它的$ e-&gt; getMessage()时,这个默认的错误信息就是你的(正确的) )得到。
你需要做的是捕获\ Illuminate \ Validation \ ValidationError - 我本来应该做的,呃! - 然后使用其方法帮助您从中提取错误消息。
以下是我提出的解决方案:
<?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);
}
}
}
所以,确实,Laravel正在提供正确的响应,并且在锡的一侧做了它所说的,但我没有正确应用它。无论如何,作为对未来我和其他在Laravel-sea失去的PHP水手的帮助,我提供了解决方案。
此外,感谢Marcin指出我的错误编码,即使我已经实施了上述解决方案,这也会引起问题。
答案 1 :(得分:4)
问题可能是Laravel的默认异常处理程序不准备将详细的验证信息传回给用户。相反,它隐藏了用户的异常细节,这通常是正确的做法,因为它可能会对其他异常形成安全风险,而不是验证异常。
换句话说;如果异常处理程序的render
函数(在/app/Exceptions/Handler.php
中实现)捕获到您的验证错误,它们将被解释为一般应用程序异常,并且重新发送给用户的一般错误消息将始终显示为& #39;给定的数据无效&#39;。
确保render
方法忽略\Illuminate\Validation\ValidationException
的实例,您应该得到预期的响应:
public function render($request, Exception $exception) {
if (! $exception instanceof \Illuminate\Validation\ValidationException)) {
// ... render code for other Exceptions here
}
}
使用响应来使异常处理程序中继ValidationException详细信息的另一种方法是在render
方法中执行类似的操作:
if ($exception instanceof ValidationException && $request->expectsJson()) {
return response()->json(['message' => 'The given data was invalid.', 'errors' => $exception->validator->getMessageBag()], 422);
}
Laravel基本上(ab)在这里使用Exceptions。通常,Exception表示代码中存在(运行时)问题,但Laravel将它们用作促进请求验证和向用户提供反馈的机制。这就是为什么,在这种情况下,让你的异常处理程序处理异常是不正确的 - 它不是一个应用程序异常,它的信息意味着用户。
OP提供的答案中的代码可以工作,因为他自己捕获ValidationException,防止它被应用程序的异常处理程序捕获。在任何情况下,我认为这都不会被通缉,因为它是一个明确的问题组合,并且会产生非常长且难以理解的代码。如上所示,简单地忽略ValidationExceptions或在异常处理程序中对它们进行不同的处理应该可以解决问题。
答案 2 :(得分:1)
您的邮件应该是验证规则,而不是:
'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',
你应该:
'name.required' => 'Name is required',
'name.alpha_num' => 'Name must be alphanumeric',
'user_id.required' => 'Curator User Id is required',
'user_id.integer' => 'Curator User Id must be an integer',
答案 3 :(得分:1)
我只是看到了这一点,但是您要做的就是在 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();
}
因为Laravel自动捕获验证异常,并以旧输入和一系列错误输出返回您,因此您可以像这样输出错误
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
答案 4 :(得分:0)
将响应放入变量中,然后使用dd()进行打印。您可以在“消息”方法中找到它。为我工作。
dd($response);