5

我們希望在accept頭中使用內容協商來實現基於版本的API。ASP.NET Web API合約版本

我們能夠實現控制器&有一些繼承的API方法並擴展了默認的HTTP選擇器。

控制器繼承使用下面的示例代碼實現,

public abstract class AbstractBaseController : ApiController 
{ 
    // common methods for all api 
} 

public abstract class AbstractStudentController : AbstractBaseController 
{ 
    // common methods for Student related API'sample 

    public abstract Post(Student student); 
    public abstract Patch(Student student); 
} 

public class StudentV1Controller : AbstractStudentController 
{ 
    public override Post([FromBody]Student student) // student should be instance of StudentV1 from JSON 
    { 
     // To Do: Insert V1 Student 
    } 

    public override Patch([FromBody]Student student) // student should be instance of StudentV1 from JSON 
    { 
     // To Do: Patch V1 Student 
    } 
} 

public class StudentV2Controller : AbstractStudentController 
{ 
    // 
    public override Post([FromBody]Student student) // student should be instance of StudentV2 from JSON 
    { 
     // To Do: Insert V2 Student 
    } 
} 

public abstract class Student 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

public class StudentV1 : Student 
{ 
} 

public class StudentV2 : Student 
{ 
    public string Email { get; set; } 
} 

我們上述架構做更少的代碼與版本變化所造成,說,如果第1版有10種API方法和存在一個API的變化方法,而不是修改其他9(它們從版本1繼承),它應該在版本2代碼中可用。

現在,我們面臨的主要問題是在合同版本控制中,因爲我們無法實例化抽象學生的實例。當有人將JSON發佈到API版本1時,StudentV1的實例應該以方法傳遞並且在版本2中相同。

有沒有什麼辦法可以實現這一點?

在此先感謝!

+3

是這樣的:http://stackoverflow.com/questions/21306305/binding-abstract-action-parameters-in-webapi –

+0

感謝@DanielStackenland! 我們沒有像productType這樣的公共字段來標識發佈的JSON。 此外,我們將有大約50-70個這樣的類,例如API中的學生,稍後將在需要時進行版本化。 –

+0

無論如何,AbstractStudentController的目的是什麼?爲什麼不讓StudentV1Controller(和V2)繼承AbstractBaseController並使用StudentV1(和V2)作爲參數? –

回答

0

根據您的粘貼代碼,您可以製作AbstractStudentController generic。 由於您聲明抽象的那些API必須在每個API版本中實現,並且您可以使用泛型定義類型。我希望我不會錯過描述中的某些內容,因爲您在StudentV2Controller中的實現中缺少Patch,但聲明爲抽象。你想從StudentV1Controller派生StudentV2Controller嗎?

public abstract class AbstractBaseController : ApiController 
{ 
    // common methods for all api 
} 

public abstract class AbstractStudentController<StudentType> : AbstractBaseController 
{ 
    // common methods for Student related API'sample 

    public abstract Post(StudentType student); 
    public abstract Patch(StudentType student); 
} 

public class StudentV1Controller : AbstractStudentController<StudentV1> 
{ 
    public override Post([FromBody]StudentV1 student) // student should be instance of StudentV1 from JSON 
    { 
     // To Do: Insert V1 Student 
    } 

    public override Patch([FromBody]StudentV1 student) // student should be instance of StudentV1 from JSON 
    { 
     // To Do: Patch V1 Student 
    } 
} 

public class StudentV2Controller : AbstractStudentController<StudentV2> 
{ 
    // 
    public override Post([FromBody]StudentV2 student) // student should be instance of StudentV2 from JSON 
    { 
     // To Do: Insert V2 Student 
    } 
}