ใครช่วยอธิบาย CreatedAtRoute () ให้ฉันฟังได้ไหม


140

จากเทมเพลตสำหรับ Web API 2 วิธีการโพสต์จะเป็นเช่นนี้เสมอ:

[ResponseType(typeof(MyDTO))]
public IHttpActionResult PostmyObject(MyDTO myObject)
{
    ...
    return CreatedAtRoute("DefaultApi", new { id = myObject.Id }, myObject);
}

ฉันไม่เข้าใจCreatedAtRoute()วิธีนี้ ใครสามารถอธิบายCreatedAtRoute()วิธีการให้ฉัน?


27
@JohnSaunders แน่นอนฉันพบผลลัพธ์ของ Google เหล่านั้น ปัญหาของฉันคือเอกสารเหล่านี้ไม่ช่วยให้ฉันเข้าใจวิธีการนี้หลังจากอ่านแล้วฉันก็ยังไม่เข้าใจ นั่นเป็นเหตุผลที่ฉันถามที่นี่
— การต่อสู้

13
ฉันไม่ให้คุณตอบคำถามของฉันแล้ว
— ศึก

14
ถ้าฉันสามารถ Google และหาคำตอบได้ทำไมฉันจึงต้องเสียเวลาแก้ไขคำถามและถามที่นี่
— การต่อสู้

4
ขอบคุณที่ถามคำถามนี้ :)
— Vidar

คำตอบ:


159

CreatedAtRouteวิธีมีจุดมุ่งหมายเพื่อกลับ URI กับทรัพยากรที่สร้างขึ้นใหม่เมื่อคุณเรียกวิธีการโพสต์ในการจัดเก็บวัตถุใหม่บางส่วน ดังนั้นหากคุณโพสต์รายการสั่งซื้อคุณอาจส่งคืนเส้นทางเช่น 'api / order / 11' (11 เป็นรหัสของคำสั่งซื้ออย่างชัดเจน)

BTW ฉันยอมรับว่าบทความ MSDN ไม่มีประโยชน์ในการทำความเข้าใจเรื่องนี้ เส้นทางที่คุณกลับจริงจะขึ้นอยู่กับการตั้งค่าเส้นทางของคุณ


13
สิ่งที่ส่งกลับมาคืออ็อบเจ็กต์ CreatedAtRouteNegotiatedContentResult <myObject>! นั่นคือสิ่งที่คุณจะเห็นหากคุณทำการทดสอบหน่วยกับการกระทำของคุณ อย่างไรก็ตามเมื่อเรียกใช้ในบริบทของ http จะส่งคืนอ็อบเจ็กต์ที่ทำให้เป็นอนุกรมในเนื้อหา แต่คุณควรเห็นส่วนหัวในการตอบกลับพร้อมลิงก์ไปยังทรัพยากร BTW ถ้าคุณคิดว่าฉันตอบคำถามคุณช่วยทำเครื่องหมายเป็นคำตอบได้ไหม ไชโย
— ดูคมชัดขึ้น

3
ขอบคุณที่ตอบคำถามของฉัน
— การต่อสู้

2
เส้นทางที่คุณระบุจะปรากฏเป็นส่วนหัวตำแหน่งในการตอบกลับ นี่เป็นพฤติกรรม REST ที่ค่อนข้างปกติ
— Jeff Martin

4
@seesharper เมื่อ MyObject ไม่ถูกส่งกลับ แต่ ... ทำไมฉันต้องส่งต่อไปยัง CreatedAtRoute? วิธีการทำกับมันคืออะไร?
— Elisabeth

6
มีวิธีใช้เส้นทางปัจจุบันหรือไม่? ตัวอย่างเช่นถ้าฉันสร้างวัตถุในตัวควบคุมไฟล์โดยใช้[Route("[controller]")]ตัวควบคุมฉันจะส่งคืนอะไร (เพื่อให้สามารถเรียกใช้การดำเนินการ GET ที่อยู่ติดกันด้วย URL เป็นต้น)
— Shimmy Weitzhandler

18

เมื่อคุณใช้ CreatedAtRoute อาร์กิวเมนต์แรกคือชื่อเมธอดของ Get to the resource เคล็ดลับที่ไม่ชัดเจนนักคือแม้จะระบุชื่อเมธอดที่ถูกต้อง แต่คุณต้องใช้ Name param ในแอตทริบิวต์ HttpGet เพื่อให้ใช้งานได้

ดังนั้นหากผลตอบแทนในโพสต์ของคุณคือ:

return CreatedAtRoute("Get", new { newModel.Id}, newModel);

แอตทริบิวต์ Get method ของคุณควรมีลักษณะเช่นนี้แม้ว่าเมธอดของคุณจะมีชื่อว่า Get:

[HttpGet("{id}", Name = "Get")]

การเรียกใช้วิธีการโพสต์ของคุณไม่เพียง แต่ส่งคืนออบเจ็กต์ใหม่ (โดยปกติเป็น JSON) แต่จะตั้งค่าส่วนหัวตำแหน่งในการตอบสนองต่อ URI ที่จะได้รับทรัพยากร


"สิ่งนี้จะไม่เพียงส่งคืนออบเจ็กต์ใหม่ (โดยปกติเป็น JSON) แต่จะตั้งค่าส่วนหัวตำแหน่งในการตอบสนองต่อ URI ที่จะได้รับทรัพยากรนั้น" โดย "นี่" คุณหมายถึง HttpGet หรือ HttpPost? นอกจากนี้คุณหมายถึงอะไรโดย "จะตั้งค่าส่วนหัวตำแหน่งในการตอบสนองต่อ URI ที่จะได้รับทรัพยากรนั้น"?
— Tran Anh Minh

"นี่" อ้างถึงเมธอด HttpPost (แก้ไขคำตอบ) สำหรับคำถามของคุณเกี่ยวกับ Location header นั่นคือ Http Header ที่ลูกค้าสามารถตัดสินใจที่จะทำบางสิ่งโดย like จะเปลี่ยนเส้นทางไปที่มันโดยอัตโนมัติ เป็น Http Response Header มาตรฐาน ( en.wikipedia.org/wiki/… )
— Scott Blasingame

โปรดอัปเดตคำตอบให้รวมความหมายของพารามิเตอร์ตัวที่ 2 และ 3 ด้วย
— ตัวแปร

2

ใน WebAPI. net core คุณใช้วิธีนี้เพื่อส่งคืนรหัส 201 ซึ่งหมายความว่าวัตถุนั้นถูกสร้างขึ้น

[Microsoft.AspNetCore.Mvc.NonAction]
public virtual Microsoft.AspNetCore.Mvc.CreatedAtRouteResult CreatedAtRoute (string routeName, object routeValues, object content);

ดังที่คุณเห็นด้านบน CreatedAtRoute สามารถรับ 3 พารามิเตอร์:

routeName คือชื่อที่คุณต้องใส่เมธอดที่จะเป็น URI ที่จะได้รับทรัพยากรนั้นหลังจากสร้าง

routeValues เป็นวัตถุที่มีค่าที่จะส่งต่อไปยังเมธอด GET ที่เส้นทางที่ตั้งชื่อ จะใช้เพื่อส่งคืนวัตถุที่สร้างขึ้น

เนื้อหา เป็นวัตถุที่สร้างขึ้น

ตัวอย่างข้างต้นแสดงการใช้งานสองวิธีของตัวควบคุมแบบง่ายด้วยเมธอด GET แบบง่ายที่มีชื่อผูกมัดและวิธีการ POST ที่สร้างวัตถุใหม่

namespace BastterAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class CompanyController : Controller
    {
        private ICompanyRepository _companyRepository;

        public CompanyController(ICompanyRepository companyRepository)
        {
            _companyRepository = companyRepository;
        }

        [HttpGet("{id}", Name="GetCompany")]
        public IActionResult GetById(int id)
        {
            Company company = _companyRepository.Find(id);

            if (company == null)
            {
                return NotFound();
            }

            return new ObjectResult(company);

        }

        [HttpPost]
        public IActionResult Create([FromBody] Company company)
        {

            if (company == null)
            {
                return BadRequest();
            }

            _companyRepository.Add(company);

            return CreatedAtRoute("GetCompany", new Company { CompanyID = company.CompanyID }, company);

        }


    }
}

สิ่งสำคัญ

  1. โปรดสังเกตว่าพารามิเตอร์แรกที่ CreatedAtRoute (routeName) ต้องเหมือนกันที่นิยามของ Name ที่เมธอด Get

  2. ออบเจ็กต์ในพารามิเตอร์ที่สองจะต้องมีฟิลด์ที่จำเป็นที่คุณใช้ในการดึงทรัพยากรในเมธอด Get คุณสามารถพูดได้ว่าเป็นส่วนย่อยของอ็อบเจ็กต์ที่สร้างขึ้นเอง

  3. พารามิเตอร์สุดท้ายคือวัตถุของ บริษัท ที่ได้รับในคำขอเนื้อหาในรูปแบบเต็ม

FINALY

ผลสุดท้ายเมื่อโพสต์เพื่อสร้าง บริษัท ใหม่ที่สร้างขึ้นใน API นี้คุณจะส่งคืนเส้นทางเช่น "api / company / {id}" ซึ่งจะส่งคืนทรัพยากรที่สร้างขึ้นใหม่ให้คุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.