如何在 C# ASP.NET WebAPI 中使用查詢字串引數進行版本控制?
WebApi 中的 **DefaultHttpControllerSelector** 類負責選擇我們在 URI 中傳送的相應控制器操作方法。
假設我們必須在查詢字串中實現版本控制,如下所示
v=1 StudentsV1Controller (Version 1) v=2 StudentsV2Controller (Version 2)
如果我們在查詢字串中傳遞版本資訊,例如 https://: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 控制器獲得的結果,並在查詢字串中進行了版本控制。

廣告
資料結構
網路
關係資料庫管理系統 (RDBMS)
作業系統
Java
iOS
HTML
CSS
Android
Python
C 語言程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP