如何在 C# ASP.NET WebAPI 中使用查询字符串参数进行版本控制?


WebApi 中的 **DefaultHttpControllerSelector** 类负责选择我们在 URI 中发送的相应控制器操作方法。

假设我们必须在查询字符串中实现版本控制,如下所示

v=1 StudentsV1Controller (Version 1)
v=2 StudentsV2Controller (Version 2)

如果我们在查询字符串中传递版本信息,例如 https://127.0.0.1:58174/api/student?v=1,则会返回 404 未找到错误响应,因为 DefaultHttpControllerSelector 中的 SelectController() 方法将查找 StudentsController,但我们只有 StudentsV1Controller 和 StudentsV2Controller。

为了处理这种情况,我们应该添加我们自己的 **CustomControllerSelector**,它实现了 DefaultHttpControllerSelector 类。

**CustomControllerSelector** −

示例

using System.Net.Http;
using System.Web;
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 = "1";
         var versionQueryString =
         HttpUtility.ParseQueryString(request.RequestUri.Query);
         if (versionQueryString["v"] != null){
            versionNumber = versionQueryString["v"];
         }
         if (versionNumber == "1"){
            controllerName = controllerName + "V1";
         }
         else if (versionNumber == "2"){
            controllerName = controllerName + "V2";
         }
         HttpControllerDescriptor controllerDescriptor;
         if (controllers.TryGetValue(controllerName, out controllerDescriptor)){
            return controllerDescriptor;
         }
         return null;
      }
   }
}

接下来我们需要用自定义控制器选择器替换默认的控制器选择器。这在 WebApiConfig.cs 文件中完成。请注意,我们正在用我们的 CustomControllerSelector 替换 IHttpControllerSelector。DefaultHttpControllerSelector 实现 IHttpControllerSelector,这就是我们替换 IHttpControllerSelector 的原因。

示例

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 }
      );
   }
}

**StudenV1Controller** −

using DemoWebApplication.Models;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace DemoWebApplication.Controllers{
   public class StudentV1Controller : ApiController{
      List<StudentV1> students = new List<StudentV1>{
         new StudentV1{
            Id = 1,
            Name = "Mark"
         },
         new StudentV1{
            Id = 2,
            Name = "John"
         }
      };
      public IEnumerable<StudentV1> 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<StudentV2> students = new List<StudentV2>{
         new StudentV2{
            Id = 1,
            FirstName = "Roger",
            LastName = "Federer"
         },
         new StudentV2{
            Id = 2,
            FirstName = "Tom",
            LastName = "Bruce"
         }
      };
      public IEnumerable<StudentV2> Get(){
         return students;
      }
      public StudentV2 Get(int id){
         var studentForId = students.FirstOrDefault(x => x.Id == id);
         return studentForId;
      }
   }  
}

输出

下面的输出显示了我们从 StudentV1 和 StudentV2 控制器获得的结果,并在查询字符串中进行了版本控制。

更新于:2020-08-19

浏览量:358

开启你的 职业生涯

通过完成课程获得认证

开始学习
广告