בפוסט הזה אדגים כמה צורות להחזיר http response מקונטרולר של asp.net web api. ועל הדרך נראה גם את הצורות הבסיסיות לכל הפעולות של CRUD.
הערה : לא תמיד אני מציג את הפונקציה במלואה, אז תתאימו את סוג המשתנה שמחזירה הפונקציה אל הדוגמא.
דוגמא 1 – להחזיר קוד Http
החזרת תשובה באמצעות אובייקט HttpResponseMessgae
return new HttpResponseMessage(HttpStatusCode.Created)
זה יחזיר תשובה 200 – כלומר "הכל תקין".
כדי להחזיר תשובה 400 באותו אובייקט , נקליד כך
return HttpResponseMessage(HttpResponseCode.BadRequest);
מתי משתמשים בזה ?
ובכן, אני מראה כאן אפשרות לשימוש, אנחנו מנסים להכניס את התוכן לדאטאבייס, אם לא מצליח, מחזירים שגיאה, אם מצליח – מחזירים הצלחה.
הדוגמא הבאה משתמשת בפועל http post :
[HttpPost("momo")]
public HttpResponseMessage Moko([FromBody]Post post)
{
try
{
this._appContext.Posts.Add(post);
if (this._appContext.SaveChanges() > 0 )
{
return new HttpResponseMessage(System.Net.HttpStatusCode.Created);
} else
{
return new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest);
}
} catch(Exception e)
{
return new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest);
}
}
דוגמא 2 – להחזיר קוד Http עם פונקציות קיצור
בשתי המקרים הקודמים היינו צריכים להגדיר את הפונקציה שתחזיר HttpResponseMessage אך לאובייקטים האלו יש פונקציות קיצור.
בדוגמא הזו הפונקציה מחזירה "כרגיל" IActionResult .
פונקציית קיצור להחזרת תשובה תקינה – -200:
return Ok("everything fine");
פונקציית קיצור להחזרת תשובה לא תקינה 400 :
return NotFound("your requested item didnt found in db");
כמובן שאת המחרוזת בתשובה אפשר לרשום כפי שרוצים.
דוגמא 3 – להחזיר מידע בתוך התשובה, באמצעות הפועל Http Get :
בדוגמא הבאה אנחנו מחזירים תשובה מסוג מאוד ספציפי – רשימה של אובייקט שאנינו יצרנו.
כמובן שהפריימוורק Asp.net יצמיד לזה קוד 200 ויחזיר את הרשימה בתור מערך JSON.
[HttpGet]
public IEnumerable<MyObj> GetAll() {
return _context.MyObj.ToList();
}
יש אפשרות כמובן גם להחזיר אובייקט מידע בודד (ולא רשימה של אובייקטים רבים).
להלן דוגמא :
[HttpGet("{id}", Name = "GetById")]
public IActionResult GetById(long id)
{
var item = _context.MyItems.FirstOrDefault(p => p.Id == id);
if (item == null)
{
return NotFound();
}
return new ObjectResult(item);
}
במקרה זה החזרנו תשובה תקינה אם הכל נמצא תקין.
ותשובת שגיאה – אם לא נמצא.
דוגמא 4 – לקבל נתונים גם מה-URL וגם מה-BODY – פעולת Update באמצעות הפועל Http Put
בפונקציה הבאה, אנחנו מקבלים 2 נתונים, אחד פרימטיבי – דרך ה-url, והשני מגיע כאובייקט בתוך ה-body של הבקשה.
התשובות שאנחנו מחזירים – הצלחה או כישלון, היא לפי מה שקורה בפועל.
שימו לב שזוהי קריאת PUT , כלומר במידה ומנסים אותה באמצעות PostMan למשל, אז צריך להגדיר את הקריאה כ-PUT.
[HttpPut("update/{id}")]
public HttpResponseMessage Update([FromRoute] int id, [FromBody]Post post)
{
try
{
Post po = _appContext.Posts.FirstOrDefault(x => x.Id == id);
if (po == null)
{
return new HttpResponseMessage(System.Net.HttpStatusCode.NotFound);
}
else
{
po.Title = post.Title;
po.Content = post.Content;
if(_appContext.SaveChanges() > 0 )
{
return new HttpResponseMessage(System.Net.HttpStatusCode.OK);
} else
{
return new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest);
}
}
}
catch (Exception e)
{
return new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest);
}
}
ישנה אפשרות נוספת לעשות פונקציה דומה, שמחזירה תשובה של IActionResult וגם משתמשת בפונקציות קיצור.
בפונקציה הבאה – אני עושה בדיוק את אותה פעולה – עדכון רשומה, רק שאני נצמד לשיטה שמוצגת באתר של מיקרוסופט :
[HttpPut("update2/{id}")]
public IActionResult Update2([FromRoute] int id, [FromBody] Post post)
{
if (post == null || post.Id != id)
{
return BadRequest();
}
Post po = _appContext.Posts.FirstOrDefault(x => x.Id == id);
if (po == null)
{
return NotFound();
}
po.Title = post.Title;
po.Content = post.Content;
_appContext.Posts.Update(po);
_appContext.SaveChanges();
return new NoContentResult();
}
בשלב זה, כבר אפשר לשאול – מה עדיף ? שימוש ב- HttpResponseMessage או החזרה של IActionResult.
אני באופן אישי מעדיף IActionResult, פשוט משום שהקוד נראה קצת יותר קצר, קריא ומסודר. מי שרוצה להרחיב יכול לעיין בקישור הזה, שמסביר את העיקרון – מדוע IActionResult עדיף מאשר HttpResponseMessage.
דוגמא 5 – פעולת מחיקה באמצעות הפועל Http Delete
כמו בדוגמא הקודמת, נדגים ראשית באמצעות החזרת HttpResponseMessage.
היות ואני לא מגדיר פה שם מפורש לניתוב ( route) אזי בעצם הניתוב של הקלאס עצמו משמש פה, בתוספת הפרמטר id שהגדרתי.
[HttpDelete("{id}")]
public HttpResponseMessage Delete([FromRoute] int id)
{
try
{
Post po = _appContext.Posts.FirstOrDefault(x => x.Id == id);
if (po == null)
{
return new HttpResponseMessage(System.Net.HttpStatusCode.NotFound);
}
else
{
_appContext.Posts.Remove(po);
if (_appContext.SaveChanges() > 0)
{
return new HttpResponseMessage(System.Net.HttpStatusCode.OK);
}
else
{
return new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest);
}
}
} catch(Exception e)
{
return new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest);
}
}
ודוגמא נוספת, לעשות את אותה פעולה, עם פונקציות קיצור ועם החזרת IActionResult .
[HttpDelete("delete2/{id}")]
public IActionResult Delete2(int id)
{
Post po = _appContext.Posts.FirstOrDefault(x => x.Id == id);
if (po == null)
{
return NotFound();
}
_appContext.Posts.Remove(po);
_appContext.SaveChanges();
return new NoContentResult();
}
מקורות נוספים :
https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-web-api
