2016-08-08 35 views
6

我需要創建一個REST web服務。 爲此我遵循本教程:http://www.odata.org/blog/how-to-use-web-api-odata-to-build-an-odata-v4-service-without-entity-framework/REST webservice WebAPI - 基於多個實體創建端點

一切工作正常,我也加入了BasicAuth,它像一個手套一樣工作。

現在,我的問題... 這個web服務將使用它的可能版本,所以我們決定實施一種版本系統。另外,我們希望客戶端應用程序選擇他們想要執行其操作的數據庫。 爲此,我們認爲,這將是不錯的URI的這種風格:

http://localhost/Connection/northwind/API/1/DataRow

這是我的代碼。我曾經只有實體DataRow的定義。現在我還定義了實體API和連接。

如何實現我想要的URI /端點? 到目前爲止,這是我的代碼。

文件:WebApiConfig.cs

using Integration.Models; 
using Microsoft.OData.Edm; 
using System.Web.Http; 
using System.Web.OData.Batch; 
using System.Web.OData.Builder; 
using System.Web.OData.Extensions; 
using Integration.Controllers; 
namespace Integration 
{ 
    public static class WebApiConfig 
    { 
     public static void Register(HttpConfiguration config) 
     { 
      config.MapODataServiceRoute("odata", null, GetEdmModel(), new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer)); 
      config.EnsureInitialized(); 
     } 
     private static IEdmModel GetEdmModel() 
     { 
      //GlobalConfiguration.Configuration.Filters.Add(new BasicAuthenticationFilter()); // basicAutenthentication 
      ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); 
      builder.Namespace = "Integration"; 
      builder.ContainerName = "DefaultContainer"; 
      builder.EntitySet<DataRow>("DataRow"); 
      builder.EntitySet<Connection>("Connection"); 
      builder.EntitySet<API>("API"); 
      var edmModel = builder.GetEdmModel(); 
      return edmModel; 
     } 
    } 
} 

控制器\ DataRows.cs

using Integration.DataSource; 
using System.Linq; 
using System.Web.Http; 
using System.Web.OData; 
using System.Net; 

namespace Integration.Controllers 
{ 
    [EnableQuery] 
    public class DataRowController : ODataController 
    { 
     [BasicAuthenticationFilter] 
     public IHttpActionResult Get() 
     { 
      return Content(HttpStatusCode.NoContent,"NoContent"); 
     } 
     [BasicAuthenticationFilter] 
     public IHttpActionResult Post(Models.DataRow row) 
     { 
      if (!ModelState.IsValid) 
      { 
       return BadRequest(ModelState); 
      } 

      //do stuff to save data 
      // .. 
      return Content(HttpStatusCode.Created, "OK"); 
     } 
    } 
} 

控制器\ Connections.cs

using Integration.DataSource; 
using System.Linq; 
using System.Web.Http; 
using System.Web.OData; 
using System.Net; 

namespace Integration.Controllers 
{ 
    [EnableQuery] 
    public class ConnectionController : ODataController 
    { 
     [BasicAuthenticationFilter] 
     public IHttpActionResult Get() 
     { 
      return Ok(IntegrationDataSources.Instance.Connection.AsQueryable()); 
     } 

     [BasicAuthenticationFilter] 
     public IHttpActionResult Post(Models.Connection connection) 
     { 
      return Content(HttpStatusCode.NotImplemented, "NotImplemented"); 
     } 
    } 
} 

型號\ DataRow.cs

using System; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 
using System.Linq; 
using System.Web; 

namespace Integration.Models 
{ 
    public class DataRow 
    { 
     [Key] 
     public int ID { get; set; } 
     [Required] 
     public int Type { get; set; } 
     [Required] 
     public string DataType { get; set; } 
     [Required] 
     public string Data { get; set; } 
     [Required] 
     public int APIVersion { get; set; } 
     [Required] 
     public string IntegrationProvider { get; set; } 
    } 
    public class Connection 
    { 
     [Key] 
     public string ConnectionName { get; set; } 
     public API Api { get; set; } 
    } 
    public class API 
    { 
     [Key] 
     public int Version { get; set; } 
     public DataRow row { get; set; } 
    } 
} 

回答

3

您可以配置API版本與全球路由前綴與屬性路由...您可以創建一個從DefaultDirectRouteProvider像一個繼承下面

public class CentralizedPrefixProvider : DefaultDirectRouteProvider 
{ 
    private readonly string _centralizedPrefix; 

    public CentralizedPrefixProvider(string centralizedPrefix) 
    { 
     _centralizedPrefix = centralizedPrefix; 
    } 

    protected override string GetRoutePrefix(HttpControllerDescriptor controllerDescriptor) 
    { 
     var existingPrefix = base.GetRoutePrefix(controllerDescriptor); 
     if (existingPrefix == null) return _centralizedPrefix; 

     return string.Format("{0}/{1}", _centralizedPrefix, existingPrefix); 
    } 
} 

一個類,並將其添加在WebApiConfig.cs這樣

config.MapHttpAttributeRoutes(new CentralizedPrefixProvider("api/v{version:int}"));

欲瞭解更多信息,你可以從這個鏈接幫助... http://www.strathweb.com/2015/10/global-route-prefixes-with-attribute-routing-in-asp-net-web-api/

2

有許多方法可以通過Web API處理版本控制:通過URI,通過查詢字符串或通過請求標頭。

最終,無論採取什麼方法,您都需要使用邏輯進行某種「控制器選擇器」抽象,以便解釋您的版本號並選擇合適的控制器。

This article在解釋基礎知識方面做得很好。

1

只是爲了拋出一個離題的想法:使用依賴注入來讓DI容器或容器定義的工廠接口創建一個由控制器使用的版本化API實例?

public interface IApiVersion { 
    //the public method signatures 
} 

public interface IApiVersionFactory { 
    IApiVersion Create(int version); 
} 

注入出廠到控制器,並調用了正確版本的API的方法,你會好到哪裏去。