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

Phiên bản hóa WebAPI với Custom Media Type trong C# ASP.NET

Media types (loại phương tiện) cho phép API thông báo cho client cách diễn giải dữ liệu trong payload. Trong giao thức HTTP, Media Types được chỉ định bằng các định danh như text/html, application/json, và application/xml, tương ứng với HTML, JSON và XML - các định dạng web phổ biến nhất. Ngoài ra còn có các Media Types đặc thù API hơn, như application/vnd.api+json.

Dưới đây là các phiên bản cần gửi trong media types:

application/vnd.demo.students.v1+json → StudentsV1Controller
application/vnd.demo.students.v2+json → StudentsV2Controller

Phiên bản hóa WebAPI với Custom Media Type trong C# ASP.NET

Việc thêm CustomControllerSelector tùy chỉnh sẽ giải quyết lỗi trên.

Triển khai CustomControllerSelector

using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
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 = "";
            string regex = @"application\/vnd\.demo\.([a-z]+)\.v(?[0-9]+)\+([a-z]+)";

            var acceptHeader = request.Headers.Accept
                .Where(a => Regex.IsMatch(a.MediaType, regex, RegexOptions.IgnoreCase));

            if (acceptHeader.Any())
            {
                var match = Regex.Match(acceptHeader.First().MediaType, regex, RegexOptions.IgnoreCase);
                versionNumber = match.Groups["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;
        }
    }
}

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ả đầu ra từ StudentV1 và StudentV2 controllers với phiên bản hóa custom media types:

Phiên bản hóa WebAPI với Custom Media Type trong C# ASP.NET

Phiên bản hóa WebAPI với Custom Media Type trong C# ASP.NET

Nếu muốn lấy kết quả tương tự ở định dạng XML sử dụng custom media type, thêm các media type tùy chỉnh vào WebApiConfig.cs:

public static void Register(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();
    config.Services.Replace(typeof(IHttpControllerSelector), new CustomControllerSelector(config));
    config.Formatters.XmlFormatter.SupportedMediaTypes
        .Add(new MediaTypeHeaderValue("application/vnd.demo.student.v1+xml"));
    config.Formatters.XmlFormatter.SupportedMediaTypes
        .Add(new MediaTypeHeaderValue("application/vnd.demo.student.v2+xml"));
    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );
}

Phiên bản hóa WebAPI với Custom Media Type trong C# ASP.NET

Trong ví dụ trên, đầu ra ở định dạng XML như được chỉ định trong custom media type.