ใครช่วยอธิบาย 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.