Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

Parameter Binding ใน C# ASP.NET WebAPI คืออะไร

Binding คือกระบวนการตั้งค่า Values ให้ Parameters เมื่อ Web API เรียก Controller Action Method

Web API Methods มี Parameter Types ต่างๆ และวิธี Customize Binding Process:

  • ถ้า Parameter เป็น Simple Type (int, bool, double, ฯลฯ) Web API พยายาม Get Value จาก URI (Route Data หรือ Query String)
  • ถ้า Parameter เป็น Complex Type (Customer, Employee, ฯลฯ) Web API Framework พยายาม Get Value จาก Request Body
  • เราสามารถเปลี่ยน Default Behavior ได้ด้วย Attributes [FromBody] และ [FromUri]

FromUri (Default สำหรับ Simple Types)

ถ้า Parameter เป็น Simple Type Web API พยายาม Get Value จาก URI

.NET Primitive Types: int, bool, double, DateTime, Guid, string, และ Type ใดๆ ที่ Convert จาก String ได้


// GET /api/student/123 → id = 123 (จาก Route Data)
// GET /api/student?id=123 → id = 123 (จาก Query String)
public Student Get(int id) { ... }

// GET /api/student?name=John&age=25
public Student Get(string name, int age) { ... }

FromBody (Default สำหรับ Complex Types)

ถ้า Parameter เป็น Complex Type Web API จะ Bind จาก Message Body (ใช้ MediaTypeFormatter)


// POST /api/student Body: { "Id": 1, "Name": "John" }
public Student Post(Student student) { ... }

// PUT /api/student/1 Body: { "Name": "Jane" }
public HttpResponseMessage Put(int id, Student student) { ... }

[FromUri] - บังคับ Bind Complex Type จาก URI


// GET /api/student?Id=1&Name=John
public Student Get([FromUri] Student student) { ... }

// Query String สำหรับ Complex Object
// ?student.Id=1&student.Name=John&student.Address.City=Bangkok
public HttpResponseMessage Get([FromUri] Student student) { ... }

[FromBody] - บังคับ Bind Simple Type จาก Request Body


// POST /api/student Body: "John" (raw string, Content-Type: text/plain)
public Student Post([FromBody] string name) { ... }

// POST /api/student Body: 25 (raw number)
public HttpResponseMessage Post([FromBody] int age) { ... }

ข้อจำกัดสำคัญ: ห้ามมี [FromBody] หลายตัวใน Action เดียว


// ❌ ผิด - มี FromBody 2 ตัว
public Student Post([FromBody] string name, [FromBody] int age) { ... }

// ✅ ถูก - ใช้ Complex Type แทน
public class StudentDto {
    public string Name { get; set; }
    public int Age { get; set; }
}

public Student Post([FromBody] StudentDto dto) { ... }

Parameter Binding Rules Summary

Parameter TypeDefault SourceForce URIForce Body
Simple (int, string, bool, DateTime, Guid, etc.)URI (Route/Query)Auto[FromBody]
Complex (Class, Array, List, etc.)Request Body[FromUri]Auto
IFormFile / HttpPostedFileBaseRequest Body (Multipart)N/AAuto
CancellationTokenAuto-injectedN/AN/A

Custom Parameter Binding (Advanced)


// Custom Model Binder
public class CommaSeparatedIntArrayBinder : IModelBinder {
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) {
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (value == null) return false;
        
        var ids = value.AttemptedValue.Split(',')
            .Select(s => int.TryParse(s, out var i) ? i : (int?)null)
            .Where(i => i.HasValue)
            .Select(i => i.Value)
            .ToArray();
        
        bindingContext.Model = ids;
        return true;
    }
}

// Usage
public IEnumerable Get([ModelBinder(typeof(CommaSeparatedIntArrayBinder))] int[] ids) { ... }
// GET /api/student?ids=1,2,3,4,5

ใน ASP.NET Core

  • [FromQuery] - แทน [FromUri] (Query String เท่านั้น)
  • [FromRoute] - Route Data เท่านั้น
  • [FromBody] - Request Body (JSON/XML/Form)
  • [FromHeader] - Request Headers
  • [FromForm] - Form Data (application/x-www-form-urlencoded)
  • [FromServices] - Dependency Injection