Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Phiên bản hóa WebAPI với Accept Header trong C# ASP.NET

Header Accept cho biết server định dạng file nào mà trình duyệt mong muốn nhận dữ liệu. Các định dạng này thường được gọi là MIME-types (Multipurpose Internet Mail Extensions).

Phiên bản hóa có thể gửi trong Headers như sau:

Version=1 → StudentsV1Controller
Version=2 → StudentsV2Controller

Phiên bản hóa WebAPI với Accept Header trong C# ASP.NET

Vì chưa xử lý version trong accept headers, ta nhận được lỗi 404 Not Found vì chỉ có StudentsV1Controller và StudentsV2Controller. Hãy thêm CustomControllerSelector triển khai từ DefaultHttpControllerSelector.

Triển khai CustomControllerSelector

using System.Linq;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Dispatcher;

namespace WebAPI.Custom
{
    public class CustomControllerSelector : DefaultHttpControllerSelector
    {
        private HttpConfiguration _config;

        public CustomControllerSelector(HttpConfiguration config) : base(config)
        {
            _config = config;
        }

        public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
        {
            var controllers = GetControllerMapping();
            var routeData = request.GetRouteData();
            var controllerName = routeData.Values["controller"].ToString();
            string versionNumber = "";

            var acceptHeader = request.Headers.Accept.Where(a => a.Parameters
                .Count(p => p.Name.ToLower() == "version") > 0);

            if (acceptHeader.Any())
            {
                versionNumber = acceptHeader.First().Parameters
                    .First(p => p.Name.ToLower() == "version").Value;
            }

            HttpControllerDescriptor controllerDescriptor;

            if (versionNumber == "1")
            {
                controllerName = string.Concat(controllerName, "V1");
            }
            else if (versionNumber == "2")
            {
                controllerName = string.Concat(controllerName, "V2");
            }

            if (controllers.TryGetValue(controllerName, out controllerDescriptor))
            {
                return controllerDescriptor;
            }

            return null;
        }
    }
}

Tiếp theo, thay thế default controller selector bằng custom controller selector trong WebApiConfig.cs. Lưu ý ta thay thế IHttpControllerSelector bằng CustomControllerSelector. DefaultHttpControllerSelector triển khai IHttpControllerSelector, đó là lý do ta thay thế IHttpControllerSelector.

Cấu hình WebApiConfig.cs

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Services.Replace(typeof(IHttpControllerSelector), new CustomControllerSelector(config));
        config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

StudentV1Controller

using DemoWebApplication.Models;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace DemoWebApplication.Controllers
{
    public class StudentV1Controller : ApiController
    {
        List students = new List
        {
            new StudentV1 { Id = 1, Name = "Mark" },
            new StudentV1 { Id = 2, Name = "John" }
        };

        public IEnumerable Get()
        {
            return students;
        }

        public StudentV1 Get(int id)
        {
            var studentForId = students.FirstOrDefault(x => x.Id == id);
            return studentForId;
        }
    }
}

StudentV2Controller

using DemoWebApplication.Models;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace DemoWebApplication.Controllers
{
    public class StudentV2Controller : ApiController
    {
        List students = new List
        {
            new StudentV2 { Id = 1, FirstName = "Roger", LastName = "Federer" },
            new StudentV2 { Id = 2, FirstName = "Tom", LastName = "Bruce" }
        };

        public IEnumerable Get()
        {
            return students;
        }

        public StudentV2 Get(int id)
        {
            var studentForId = students.FirstOrDefault(x => x.Id == id);
            return studentForId;
        }
    }
}

Kết quả từ StudentV1 và StudentV2 controllers với phiên bản hóa trong accept headers:

Phiên bản hóa WebAPI với Accept Header trong C# ASP.NET

Phiên bản hóa WebAPI với Accept Header trong C# ASP.NET