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