PDA

View Full Version : دریافت خطاهای ModelState از web api core



payam64
سه شنبه 10 تیر 1399, 20:56 عصر
سلام توی این پست میخوام در مورد استخراج کردن خطاهای رخ داده در web api با استفاده از ModelState مطلبی قرار بدم
مطمئنا بیشترین نوع خطایی که در متد اکشن های web api برای پاسخ استفاده میشه BadRequest هست که یک ورودی از نوع ModelState برای خطاهای شما میگیره این خطاها میتونه در زمان اعتبارسنجی داده انجام شده باشه و یا بخشی از بیزینس شما که بصورت دستی خطایی رو تولید کردین و برای ux بهتر به کلاینت ارسال میکنین

نمونه کد مربوط به یک اکشن متد web api برای زمانیکه باید badrequest به سمت کلایت ارسال کنید


[HttpPost]
[ProducesResponseType(StatusCodes.Status400BadReque st)]
[ProducesResponseType(StatusCodes.Status201Created)]
public virtual async Task<ActionResult<T>> CreateEntity(TEntity newEntity)
{
if (!ModelState.IsValid) return BadRequest(ModelState);


var entity = await _genericRepository.Create(_mapper.Map<TEntity, T>(newEntity));
if (entity != null)
return Created(new Uri(returnUri), entity);


ModelState.AddModelError(string.Empty, "خطا در ثبت داده");
return BadRequest(ModelState);
}

توی اکشن متد اول اعتبارسنجی بررسی شده و در صورت اوکی نبودن همون ModelState به خروجی به همراه کد 400 به کلاینت ارسال میشه و یا در آخر متداکشن به شکل دستی خطایی به ModelState اضافه شده و به سمت کلاینت ارسال میشه

اما در سمت کلاینت از یک کلاس که میتونه به صورت توسعه یافته تعریف شده در زمان های دریافت پاسخ از سمت سرویس استفاده بشه :

public static class GetHttpResponseMessageErrors {
public static List<string> GetHttpErrors(
this HttpResponseMessage httpResponse, string message = "")
{
List<string> errors = new List<string>();
if (httpResponse.StatusCode == HttpStatusCode.BadRequest)
{
var httpErrorObject = httpResponse.Content.ReadAsStringAsync().Result;
var anonymousErrorObject = new { errors = new Dictionary<string, string[]>() };
var deserializedErrorObject =
JsonConvert.DeserializeAnonymousType(httpErrorObje ct, anonymousErrorObject);
if (deserializedErrorObject != null)
{
errors.AddRange(deserializedErrorObject.errors.Sel ectMany(error => error.Value));
}
}
return errors;
}
}

در کد بالا یک نمونه از پاسخ دریافتی از سرویس دریافت شده و با استفاده از متد ReadAsStringAsync پاسخ دریافتی به شکل Json دریافت میشه و در دو خط بعدی اول قالب کلی مدلی که ModelState قرار برای ما برگردونه مشخص شده و اون شی json دریافتی با استفاده از فرمت مشخص شده Deserialize شده البته به دلیل تعریف نوع قالب بازگشتی که بصورت شخصی سازی شده از متد DeserilizeAnonymousType استفاده می کنیم
در نهایت در زمان دریافت پاسخ از سمت سرویس در صورت عدم دریافت اوکی و یا هر پاسخ دیگه ای که منتظرش هست باید خطاهای رخ داده را استخراج کنه

using (var client = new HttpClient){
BaseAddress = new Uri("http://localhost:5773/");
HttpResponseMessage responseMessage;
responseMessage = await client.PostAsync(uriPath, data);
if (!responseMessage.IsSuccessStatusCode){
var errors = responseMessage.GetHttpErrors();
}
};