오류 처리(ex 발송).고객에게 보내는 메시지)
ASP를 가지고 있습니다.NET Core 1.0 Web API 응용 프로그램에서 컨트롤러에서 호출하는 함수가 오류를 발생시킬 경우 클라이언트에 예외 메시지를 전달하는 방법을 확인하려고 합니다.
나는 많은 것을 시도했지만 실행되는 것은 아무것도 없습니다.IActionResult
.
나는 왜 이것이 사람들이 필요로 하는 흔한 것이 아닌지 이해할 수 없습니다.만약 진실로 해결책이 없다면 누가 이유를 말해줄 수 있습니까?
다음을 사용하여 문서를 봅니다.HttpResponseException(HttpResponseMessage)
하지만 이것을 사용하기 위해서는 compat shim을 설치해야 합니다.Core 1.0에서 이러한 작업을 수행하는 새로운 방법이 있습니까?
여기 심으로 시도해 봤는데 작동하지 않는 것이 있습니다.
// GET: api/customers/{id}
[HttpGet("{id}", Name = "GetCustomer")]
public IActionResult GetById(int id)
{
Customer c = _customersService.GetCustomerById(id);
if (c == null)
{
var response = new HttpResponseMessage(HttpStatusCode.NotFound)
{
Content = new StringContent("Customer doesn't exist", System.Text.Encoding.UTF8, "text/plain"),
StatusCode = HttpStatusCode.NotFound
};
throw new HttpResponseException(response);
//return NotFound();
}
return new ObjectResult(c);
}
그 때.HttpResponseException
클라이언트를 보고 내용에서 보내는 메시지를 찾을 수 없습니다.
여기 간단한 오류 DTO 클래스가 있습니다.
public class ErrorDto
{
public int Code {get;set;}
public string Message { get; set; }
// other fields
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
}
그런 다음 ExceptionHandler 미들웨어를 사용합니다.
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
context.Response.StatusCode = 500; // or another Status accordingly to Exception Type
context.Response.ContentType = "application/json";
var error = context.Features.Get<IExceptionHandlerFeature>();
if (error != null)
{
var ex = error.Error;
await context.Response.WriteAsync(new ErrorDto()
{
Code = <your custom code based on Exception Type>,
Message = ex.Message // or your custom message
// other custom data
}.ToString(), Encoding.UTF8);
}
});
});
예. 상태 코드를 필요한 대로 변경할 수 있습니다.
사용자 지정ExceptionFilterAttribute.cs 파일은 다음과 같이 코드를 수정합니다.
public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(ExceptionContext context)
{
var exception = context.Exception;
context.Result = new ContentResult
{
Content = $"Error: {exception.Message}",
ContentType = "text/plain",
// change to whatever status code you want to send out
StatusCode = (int?)HttpStatusCode.BadRequest
};
}
}
거의 다 됐어요.
사용자 지정 예외가 있는 경우 컨텍스트에서 사용자 지정 예외를 가져올 때 해당 예외를 확인할 수도 있습니다.그런 다음 코드에서 발생한 상황에 따라 다른 HTTP 상태 코드를 보낼 수 있습니다.
도움이 되길 바랍니다.
아래와 같은 사용자 지정 예외 필터를 만들 수 있습니다.
public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(ExceptionContext context)
{
var exception = context.Exception;
context.Result = new JsonResult(exception.Message);
}
}
그런 다음 위의 특성을 컨트롤러에 적용합니다.
[Route("api/[controller]")]
[CustomExceptionFilter]
public class ValuesController : Controller
{
// GET: api/values
[HttpGet]
public IEnumerable<string> Get()
{
throw new Exception("Suckers");
return new string[] { "value1", "value2" };
}
}
예외를 제기하고 파악하는 대신 다음과 같은 작업을 간소화하는 것이 어떻습니까?
// GET: api/customers/{id}
[HttpGet("{id}", Name = "GetCustomer")]
public IActionResult GetById(int id)
{
var customer = _customersService.GetCustomerById(id);
if (customer == null)
{
return NotFound("Customer doesn't exist");
}
return Ok(customer);
}
저는 텍스트 대신 JSON 객체를 반환하는 등의 옵션을 추가하여 블로그 게시물을 작성했습니다.
아마도 그것은 도움이 될 것입니다.당신은 그냥 돌아올 수 있습니다.object
그리고 예를 들어 a를 보냈습니다.BadRequest
(HTTP 코드: 400) 및 사용자 정의object
실제 매개 변수(여기서는 보간된 문자열을 사용했습니다)로 지정할 수 있지만, 무엇이든 입력할 수 있습니다.
클라이언트 측에서는 예를 들어 AJAX 오류 처리기를 통해 해당 오류 상황을 파악할 수 있습니다.
// GET: api/TruckFahrerGeoData
[HttpGet]
public object GetTruckFahrerGeoData()
{
var truckFahrerGeoDataItems = new List<TruckFahrerGeoDataViewModel>();
var geodataItems = _context.TruckFahrerGeoData;
foreach (var truckFahrerGeoData in geodataItems)
{
GeoTelemetryData geoTelemetryData = JsonConvert.DeserializeObject<GeoTelemetryData>(truckFahrerGeoData.TelemetryData);
if (geoTelemetryData == null)
{
return BadRequest($"geoTelemetryData null for id: {truckFahrerGeoData.Id}");
}
TruckFahrerGeoDataViewModel truckFahrerGeoDataViewModel = new TruckFahrerGeoDataViewModel
{
Speed = geoTelemetryData.Speed,
Accuracy = geoTelemetryData.Accuracy,
TruckAppId = geoTelemetryData.Activity.TruckAppId,
TruckAuftragStatusId = geoTelemetryData.Activity.TruckAuftragStatusId,
ClId = geoTelemetryData.Activity.ClId,
TruckAuftragLaufStatusId = geoTelemetryData.Activity.TruckAuftragLaufStatusId,
TaskId = geoTelemetryData.Activity.TaskId,
TruckAuftragWorkflowStatusId = geoTelemetryData.Activity.TruckAuftragWorkflowStatusId
};
truckFahrerGeoDataItems.Add(truckFahrerGeoDataViewModel);
}
return truckFahrerGeoDataItems;
}
또는 더 깨끗한 방법으로IActionResult
그런 식으로:
// GET: api/TruckFahrerGeoData
[HttpGet]
public IActionResult GetTruckFahrerGeoData()
{
var truckFahrerGeoDataItems = new List<TruckFahrerGeoDataViewModel>();
var geodataItems = _context.TruckFahrerGeoData;
foreach (var truckFahrerGeoData in geodataItems)
{
GeoTelemetryData geoTelemetryData = JsonConvert.DeserializeObject<GeoTelemetryData>(truckFahrerGeoData.TelemetryData);
if (geoTelemetryData == null)
{
return BadRequest($"geoTelemetryData null for id: {truckFahrerGeoData.Id}");
}
TruckFahrerGeoDataViewModel truckFahrerGeoDataViewModel = new TruckFahrerGeoDataViewModel
{
Speed = geoTelemetryData.Speed,
Accuracy = geoTelemetryData.Accuracy,
TruckAppId = geoTelemetryData.Activity.TruckAppId,
TruckAuftragStatusId = geoTelemetryData.Activity.TruckAuftragStatusId,
ClId = geoTelemetryData.Activity.ClId,
TruckAuftragLaufStatusId = geoTelemetryData.Activity.TruckAuftragLaufStatusId,
TaskId = geoTelemetryData.Activity.TaskId,
TruckAuftragWorkflowStatusId = geoTelemetryData.Activity.TruckAuftragWorkflowStatusId
};
truckFahrerGeoDataItems.Add(truckFahrerGeoDataViewModel);
}
return Ok(truckFahrerGeoDataItems);
}
파티에 늦었지만 답을 다듬고 있습니다.
아래 최소 속성으로 오류 응답 클래스 정의
using Microsoft.AspNetCore.Http;
public class ErrorResponse
{
private readonly RequestDelegate next;
public ErrorResponse(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context )
{
try
{
await next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private static Task HandleExceptionAsync(HttpContext context, Exception ex)
{
var code = HttpStatusCode.InternalServerError;
string result = string.Empty;
object data = new object();
if (ex is ForbiddenException)
{
code = HttpStatusCode.Forbidden;
result = JsonConvert.SerializeObject(new Response<object>(Status.Forbidden(ex.Message), data));
}
else if(ex is BadRequestException){
code = HttpStatusCode.BadRequest;
result = JsonConvert.SerializeObject(new Response<object>(Status.BadRequest(ex.Message), data));
}
else if (ex is NotFoundException)
{
code = HttpStatusCode.NotFound;
result = JsonConvert.SerializeObject(new Response<object>(Status.NotFound(ex.Message), data));
}
else if (ex is UnauthorizedException)
{
code = HttpStatusCode.Unauthorized;
result = JsonConvert.SerializeObject(new Response<object>(Status.Unauthorized(ex.Message), data));
}
else
{
result = JsonConvert.SerializeObject(new Response<object>(Status.InternalServerError(ex.Message), data));
}
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)code;
return context.Response.WriteAsync(result);
}
}
다음에는 이 클래스를 startup.cs 클래스의 미들웨어로 사용합니다.
app.UseHttpsRedirection();
app.UseMiddleware(typeof(ErrorResponse));
이제 각 요청 및 응답이 이 클래스를 통과합니다. 오류가 발생하면 오류 코드가 true로 설정되고 오류 코드가 true로 설정됩니다.아래와 같은 응답 예
data: {}
status: {
code: 404
error: true
message: "No employee data found"
type: "Not Found"
}
저도 같은 문제가 있었고 몇 가지 조사 후에 HttpClient를 사용하여 API를 호출하고 응답을 쉽게 읽을 수 있다는 것을 알게 되었습니다.HttpClient는 HTTP 응답에 오류 코드가 포함된 경우 오류를 발생시키지 않지만 IsSuccessStatusCode 속성을 false로 설정합니다.
이것은 HttpClient를 사용하는 제 기능입니다.저는 이것을 제 컨트롤러에서 부릅니다.
public static async Task<HttpResponseMessage> HttpClientPost(string header, string postdata, string url)
{
string uri = apiUrl + url;
using (var client = new HttpClient())
{
//client.BaseAddress = new Uri(uri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", header);
HttpResponseMessage response = await client.PostAsync(uri, new StringContent(postdata));
return response;
}
}
이것은 제 컨트롤러 코드입니다. 함수를 호출하여 응답을 읽고 오류 여부를 판단하여 응답합니다.IsSuccessStatusCode를 확인하고 있습니다.
HttpResponseMessage response;
string url = $"Setup/AddDonor";
var postdata = JsonConvert.SerializeObject(donor);
response = await ApiHandler.HttpClientPost(HttpContext.Session.GetString(tokenName), postdata, url);
//var headers = response.Headers.Concat(response.Content.Headers);
var responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
tnxresult = JsonConvert.DeserializeObject<TnxResult>(AppFunctions.CleanResponse(responseBody));
return Json(new
{
ok = true,
message = tnxresult.Message,
statusCode = tnxresult.StatusCode
});
}
else
{
ApiError rs = JsonConvert.DeserializeObject<ApiError>(AppFunctions.CleanResponse(responseBody));
return Json(new
{
ok = false,
message = rs.Message,
statusCode = rs.StatusCode
});
}
내 API가 JSON에서 오류 메시지를 반환합니다.통화가 성공하면 저는 JSON에서도 응답을 포장하고 있습니다.
중요한 코드는 이것입니다.
var responseBody = await response.Content.ReadAsStringAsync();
HTTP 콘텐츠를 비동기 작업으로 문자열로 직렬화합니다.
그런 다음 JSON 문자열을 개체로 변환하고 오류/성공 메시지와 상태 코드에 액세스할 수 있습니다.
언급URL : https://stackoverflow.com/questions/38014379/error-handling-sending-ex-message-to-the-client
'programing' 카테고리의 다른 글
JSON 시간 초과 처리 가져오기 (0) | 2023.08.28 |
---|---|
CLOB 대 VARCHAR2 및 다른 대안이 있습니까? (0) | 2023.08.28 |
jQuery 데이터 테이블:3자를 입력하거나 버튼을 클릭할 때까지 검색 지연 (0) | 2023.08.23 |
data-false="false"는 실제로 무엇을 합니까? (0) | 2023.08.23 |
어레이가 비어 있는지 null인지 확인합니다. (0) | 2023.08.23 |