2016-08-08 82 views
6

Ich muss einen REST-Webservice erstellen. Dazu folgte ich diesem Tutorial: http://www.odata.org/blog/how-to-use-web-api-odata-to-build-an-odata-v4-service-without-entity-framework/REST webservice WebAPI - Endpunkt basierend auf mehreren Entitäten erstellen

Alles hat gut funktioniert, ich habe auch BasicAuth hinzugefügt, es funktioniert wie ein Handschuh.

Nun, meine Frage ... Dieser Webservice wird mit möglichen Versionen davon arbeiten, also haben wir uns entschieden, eine Art von Versions-Systemen zu implementieren. Außerdem möchten wir, dass die Clientanwendungen die Datenbank auswählen, für die sie ihre Aktionen ausführen möchten. Dafür, dachten wir, dass es schön URIs mit diesem Stil haben würde:

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

Dies ist der Code, den ich habe. Ich habe nur die Entität DataRow definiert. Jetzt habe ich auch die Entity API und Connection definiert.

Wie implementiere ich einen URI/Endpunkt wie ich will? Das ist der Code, den ich bisher habe.

Datei: 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; 
     } 
    } 
} 

Controller \ 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"); 
     } 
    } 
} 

Controller \ 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"); 
     } 
    } 
} 

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

Antwort

3

Sie können API Versionierung mit Global Routen Präfixe mit Attribut Routing Config ... Sie können eine Klasse erstellen, die von DefaultDirectRouteProvider wie ein von unten

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

und fügen Sie ihn in WebApiConfig.cs wie dieses

erbt

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

weitere Informationen Sie Hilfe von diesem Link bekommen ... http://www.strathweb.com/2015/10/global-route-prefixes-with-attribute-routing-in-asp-net-web-api/

2

Es gibt verschiedene Möglichkeiten, die Versionierung mit der Web-API zu handhaben: über den URI, über die Abfragezeichenfolge oder über den Anforderungsheader.

Schließlich müssen Sie eine beliebige Art von "Controller Selector" -Abstraktion mit Logik für die Interpretation Ihrer Versionsnummer und die Auswahl des entsprechenden Controllers, egal welchen Ansatz Sie nehmen.

This article macht einen guten Job, die Grundlagen zu erklären.

1

Nur um eine verrückte Idee auf Sie zu werfen: Was ist mit der Verwendung der Abhängigkeitsinjektion, um entweder den DI-Container oder eine containerdefinierte Factory-Schnittstelle zu haben, um eine Instanz Ihrer versionierten API für den Controller zu erstellen?

public interface IApiVersion { 
    //the public method signatures 
} 

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

die Fabrik in die Steuerung eingespritzt und die Methoden für die korrekt versioniert API aufrufen, und Sie würden gut zu gehen.